0

我有一个UISlider放置在我的主视图中,并且我添加了一个UIView与它自己的类相关联的子视图(通过界面生成器)SecondView。我需要将滑块的值传递给我的子视图,以便在滑块更改时在子视图中移动一个点。

我对原始代码进行了更改,以下段落不再准确。我使用了@MatthiasBauch 提供的建议更改。

我认为在两者之间共享 iVar 会很简单。我在我的界面中myPoint使用@property(如果这仍然被认为是 iVar)创建了一个 iVar ViewControllermyPoint = sliderValue.value在我的ViewController实现中设置IBAction为当滑块值发生变化时。然后在我的SecondView实现中,我在我的实现中#import "ViewController.h"调用我的调用我的 iVar,SecondView但我完成它的方式只返回nil0而不是滑块值。

我不想使用全局变量。

我看过其他似乎在问类似问题的帖子,但我想我仍然错过了这个概念。我的代码如下。

视图控制器.h

#import <UIKit/UIKit.h>
#import "SecondView.h"

@interface ViewController : UIViewController
{
    SecondView *secondView; // Do I need this with secondView declared as a @property below?
}

@property (nonatomic, retain) SecondView *secondView;

- (IBAction)sliderChanged:(id)sender;

@property (weak, nonatomic) IBOutlet UISlider *sliderValue;

@property (weak, nonatomic) IBOutlet UILabel *myLabel;

@property (weak, nonatomic) IBOutlet UIView *myView;

@end

视图控制器.m

#import "ViewController.h"
#import "SecondView.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize sliderValue, myLabel, myView, secondView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    secondView.thePoint = 50;
    NSLog(@"%f", secondView.thePoint); // This is retuning a zero
}

- (IBAction)sliderChanged:(id)sender
{
    secondView.thePoint = sliderValue.value;
    myLabel.text = [NSString stringWithFormat:@"%.2f", sliderValue.value];
    [secondView setNeedsDisplay];
}

@end

第二视图.h

#import <UIKit/UIKit.h>

@interface SecondView : UIView

@property (assign, nonatomic) CGFloat thePoint;

@end

第二视图.m

#import "SecondView.h"

@implementation SecondView

@synthesize thePoint;

- (void)drawRect:(CGRect)rect
{
    float aPoint = thePoint;
    NSLog(@"%f", aPoint); // this is retuning 0.000000
    UIBezierPath *point = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(aPoint, 100, 4, 4)];
    [point fill];
}

@end
4

2 回答 2

2

告诉视图在哪里绘制并且不要询问(新分配的)viewController 在哪里绘制。

您正在分配一个新的 viewController,这个 viewController 当然不知道您在实际更改滑块的 viewController 中设置的值。
这行不通。这两个 viewController 不是同一个实例。他们共享同一个班级,但仅此而已。来自一个 viewController 实例的值不会神奇地出现在第二个实例中。

相反,您应该在滑块操作中设置辅助视图的点属性。

像这样的东西:

将浮动 @property 添加到您的视图中

@interface SecondView : UIView
@property (assign, nonatomic) CGFloat point;
@end

绘制使用该点而不是新 ViewController 实例的初始值。

- (void)drawRect:(CGRect)rect
{
    float aPoint = self.point;

    UIBezierPath *point = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(aPoint, 100, 4, 4)];
    [point fill];
}

并在滑块动作中设置辅助视图的点属性

- (IBAction)sliderChanged:(id)sender
{
    secondView.point = sliderValue.value;
    [secondView setNeedsDisplay];         // you might be able to omit that

    myLabel.text = [NSString stringWithFormat:@"%.2f", myPoint];
}
于 2013-06-12T03:26:58.833 回答
-1

您的 ViewController 有一个名为的属性@myView,它指向运行时创建的 SecondView 实例。

因此,您的 ViewController 的实现可以调用该drawRect:方法myView并传入相关坐标。

这是您的 ViewController 的一些伪代码。

- (IBAction)sliderChanged:(id)sender
{
    myPoint = sliderValue.value;
    myLabel.text = [NSString stringWithFormat:@"%.2f", myPoint];

    [myView drawRect:CGRectMake(myPoint, 100, 4, 4)];
}

但是请注意,在您的 ViewController 中,myView它只是一个 UIView,而不是 SecondView。对于如何解决这个问题,您有几个选择。最干净的方法可能是#import ViewController.h从 SecondView 中删除,而是做相反的事情。也就是说,让 ViewController 做一个#import SecondView.h,然后提升myView到一个 SecondView。

如果由于某种原因这不起作用(例如,如果 XCode 要求它严格保持为 UIView),您仍然可以myView在运行时向上转换该属性,如下所示:

    [(*SecondView)myView drawRect:CGRectMake(myPoint, 100, 4, 4)];

或者,您可以将滑块的操作指向 myView,就像这个问题的答案对按钮所做的那样:subclass UIView actions in viewcontroller

与编程一样,有几种可能的解决方案。由您来选择最适合您的。祝你好运!

于 2013-06-12T03:09:40.203 回答