ios viewcontroller视图图片生活在Mutable Array中

早上好,

我试图实现的是在视图内绘制图形,同时通过阵列将数据添加到VC中。

到目前为止,我有一个VC和一个拥有自己的类的视图。 在课堂内部,drawRect内部生成随机数字,它们以点的形式出现在屏幕上。 到现在为止还挺好。

我想要做的是在ViewController中生成数字(或通过外部源获取它们),将它们保存在一个mutableArray中,在类中检索它们并将它们用于图形。

我在两年前在SO上发现了一个类似的问题,所以对此没有任何评论。 问题是:我在FirstViewController上有一个float值的数组。 我需要传递给我的View this数组

推荐的解决方案被标记为正常工作:

在你的FirstViewController.h中编写

#include <UIKit/UIKit.h>
extern NSArray *yourArray;

并在您的FirstViewController.m写

#import "FirstViewController.h"
@interface FirstViewController ()
@end
NSArray *yourArray;

现在,您必须在“MyView”类中导入整个FirstViewController。 在MyView.m中简单地#导入“FirstViewController.h”。 这样做后,“yourArray”将在MyView中可用。

我完全按照它的说法,然后初始化我的Array,将值放入它,NSLog在VC中检查所有工作正常,它确实如此。 当我尝试在我的视图和NSLog中检索一个值时,它说数组中的值是(null)。 代码非常简单,我几乎没有什么可以显示的:

在我的VC.h中

extern NSMutableArray *yourArray;

在我的VC.m实现中

NSMutableArray *yourArray;

在我的VC.m viewDidLoad

NSMutableArray *yourArray = [[NSMutableArray alloc] init];
[yourArray insertObject:@"Works" atIndex:0];
NSString *object = [yourArray objectAtIndex:0];
NSLog (@"the item in Array in VC is %@", object);

在我看来,

#import "GraphViewController.h"

然后我尝试添加:

NSString *object = [yourArray objectAtIndex:0];
NSLog (@"the item in Array in View is %@", object);

in(void)awakeFromNib,in(id)initWithFrame:(CGRect)frame,in(void)updateValues和in(void)drawRect:(CGRect)rect

它在我放置的任何地方都不起作用。 我完全丧失了。

请有人指点我正确的方向?

谢谢,

=============================================


我会尝试一点点地经历这一点。

你有:UIViewController的一个子类叫GraphViewController。 UIView的一个子类叫做MyGraphView。 故事板。

在故事板中,您有一个包含UIView对象的UIViewController场景。 在“Identity Inspector”中,您已将UIViewController场景“Custom Class”字段设置为GraphViewController。 正确? 同样在Identity Inspector中,您已将UIView对象Custom Class字段设置为MyGraphView。 正确?

因此,当您右键单击从View对象拖动到GraphViewController的头文件时,弹出窗口显示可供您输入属性名称,并且该弹出窗口的“Type”字段已被设置为MyGraphView。 正确?

在设置了IBOutlet属性后,您可以在故事板中选择GraphViewController,并显示Connections Inspector并查看是否存在连接到GraphViewController的名为MyGraphView的引用Outlet。

所以如果所有这些都是真的,那么你的viewController和View就是在storyboard中设置的。

GraphViewController有一个叫做yourArray的NSMutableArray属性。 GraphViewController有一个属性,它是一个名为myView的MyGraphView。 MyGraphView有一个叫做graphDataArray的NSArray属性。

所以在你的GraphViewController上面粘贴这个方法-viewDidLoad。

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.yourArray = [@[@"Testing"] mutableCopy];
    if (self.myView == nil) {
        NSLog(@"The Instance of MyGraphView called MyView does not exist");
        return;
    }else{
        NSLog(@"The Instance of MyGraphView called MyView exists %@",self.myView);
    }
    self.myView.graphDataArray = [self.yourArray copy];
    if (self.myView.graphDataArray == nil) {
        NSLog(@"GraphDataArray is nil");
    }else {
        NSLog(@"Object at index 0 = %@",self.myView.graphDataArray[0]);
        NSLog(@"MyGraphView can now receive arrays from GraphViewController :]");
    }
}

好吧,让我们先让GraphViewController中的数组工作,然后再担心视图。

从另一个堆栈溢出问题中删除你使用的代码并给你一些新东西比较容易。

// in GraphViewController.m file
#import "GraphViewController.h"
@interface GraphViewController ()
// create a property that you can access elsewhere using self.yourArray
@property (nonatomic, strong) NSMutableArray *yourArray;
@end

@implementation GraphViewController

-(void)viewDidLoad{
    [super viewDidLoad];
    self.yourArray = [@[@"Works1",@"Works2",@"StillWorks"] mutableCopy];
    NSLog (@"the item in Array in VC is %@", self.yourArray[0]);
    NSLog (@"the item in Array in VC is %@", self.yourArray[1]);
    NSLog (@"the item in Array in VC is %@", self.yourArray[2]);
}

视图类

// In AAAView.h declare this property
@property (nonatomic, strong) NSArray *graphDataArray;

然后,当你想从你的ViewController传递数组到你的视图时,你可以这样做

// yourAAAView is the instance of the view you have in your ViewController
yourAAAView.graphDataArray =  [self.dataArray copy];

// ***************************************

  • 在GraphViewController中为您的视图创建一个IBOutlet,我们将其称为“myView”
  • 在-viewDidLoad中填充你需要绘制点的值。
  • 如果你正在使用浮点数,双精度或整数等,你需要将这些值包含在NSNumber中,然后才能将它们添加到数组中。
  • 如果您正在使用CGPoints,则需要将这些值包装到NSValue中,然后才能将其添加到数组中
  • 一旦数组将所有值传递给self.myView
  • self.myView.graphDataArray = self.yourArray;
  • 在YourView类-drawRect中,您需要从self.graphDataArray获取值并使用它们绘制点。
  • 检查self.graphDataArray是否为零,如果是则返回。 尝试使用不存在的数组没有意义。
  • 我猜你最初使用了for循环,所以你会想要做这样的事情:
  •   for(int i = 0; i< [self.graphDataArray count]; i++) {
            // get object (NSNumber or NSValue) from array
                 // NSNumber *num = self.graphDataArray[i];
                 // NSValue *val = self.graphDataArray[i];
            // unwrap the value you stored in the object (float or CGpoint etc)
            // use those values to draw the dots the same way you did before
       }
    

    如果要将这些点渲染到视图,则不需要维护单独的点阵列。 UIBezierPath维护自己的点数组。 而不是传递一个点数组,将这些点传递给UIBezierPath对象点数组。

    下面的UIView代码是我用来渲染一个图形,实时和实时(每秒30次),因为我的Core Data数据库更新了新的记录:

    //
    //  GraphView.h
    //  DemonNetDAQClient
    //
    //  Created by James Bush on 5/3/17.
    //  Copyright © 2017 James Bush. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import <CoreGraphics/CoreGraphics.h>
    #import <QuartzCore/QuartzCore.h>
    
    typedef void(^PointBlock)(id path);
    
    @interface GraphView : UIView
    
    - (void)addPoint:(PointBlock)block;
    
    @end
    

    在UIView头文件中,我设置了一个将临时UIBezierPath对象传递给UIViewController的块,该UIViewController将创建一个附加到绘制UIView中图形的UIBezierPath的路径。

    这是我的GraphView.m:

    //
    //  GraphView.m
    //  DemonNetDAQClient
    //
    //  Created by James Bush on 5/3/17.
    //  Copyright © 2017 James Bush. All rights reserved.
    //
    
    #import "GraphView.h"
    #import "GraphViewController.h"
    
    @interface GraphView ()
    
    @property (strong, nonatomic) UIBezierPath *graph;
    
    @end
    
    @implementation GraphView
    
    - (void)drawRect:(CGRect)rect {
        [[UIColor redColor]setStroke];
        [self.graph stroke];
    }
    
    - (void)addPoint:(PointBlock)block {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            UIBezierPath *graphTmp = [UIBezierPath bezierPath];
            [graphTmp moveToPoint:[self.graph currentPoint]];
            block(graphTmp);
            [self.graph appendPath:graphTmp];
        });
    }
    
    - (UIBezierPath *)graph {
        UIBezierPath *g = self->_graph;
        if (!g) {
            g = [UIBezierPath bezierPath];
            [g moveToPoint:CGPointMake(0.0, CGRectGetMidY(self.frame))];
            self->_graph = g;
        }
    
        return g;
    }
    
    @end
    

    每当一个新的对象被插入到我的Core Data数据库中时(正如我的NSFetchedResultsControllerDelegate / UIViewController检测到的那样),就会调用addPoint方法。 当被调用时,UIViewController被传递一个块,并引用它在UIView中创建的临时UIBezierPath对象,它将添加一个点。 当该块返回到UIView方法时,新配置的临时UIBezierPath对象将追加到由UIView呈现的UIBezierPath。 所有点数据都使用该UIBezierPath对象进行维护。

    注| 我编写了一个独立的方法来创建UIBezierPath对象,以便将它的第一个点指向图视图中的适当位置,尽管我可以在awakeFromNib方法中以两行完成此操作。 我这样做是为了兼容与故事板和视图以编程方式实例化的视图(不要在没有故事板的情况下调用awakeFromNib)。

    以下是相关的UIViewController代码,它从NSFetchedResultsController获取点数据(我相信您已经认识并且已经熟悉,并且使用了表视图控制器 - 都是同样的事情):

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
           atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
          newIndexPath:(NSIndexPath *)newIndexPath {
        switch(type) {
            case NSFetchedResultsChangeInsert: {
                Metric *metric = (Metric *)anObject;
                double measurement = metric.metricMeasurement;
                CGFloat y = [self convertMetricToPoint:measurement];
                [(GraphView *)self.graphView addPoint:^(id path) {
                    CGPoint newPoint = CGPointMake([path currentPoint].x + 1.0, y);
                    [path addLineToPoint:newPoint];
                    [path moveToPoint:newPoint];
                }];
                break;
            }
            case NSFetchedResultsChangeDelete: {
    
                break;
            }
            case NSFetchedResultsChangeUpdate: {
    
                break;
            }
            case NSFetchedResultsChangeMove: {
    
                break;
            }
        }
    }
    
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
        [self.graphView setNeedsDisplay];
    }
    
    - (CGFloat)convertMetricToPoint:(double)metric {
        double maxPointValue    = ([(NSNumber *)[self valueForKeyPath:@"fetchedResultsController.fetchedObjects.@max.metricMeasurement"] doubleValue]);
        double normalizedMetric = (metric / maxPointValue) * self.graphView.frame.size.height;
    
        return (CGFloat)normalizedMetric;
    }
    

    你想看到这在行动? 这是一个视频:

    <iframe width="1280" height="720" src="https://www.youtube.com/embed/JYF2ZSEgOrg" frameborder="0" allowfullscreen></iframe>
    链接地址: http://www.djcxy.com/p/14383.html

    上一篇: ios viewcontroller view graph live with Mutable Array

    下一篇: bottom instead of left