将滑块值传递给子视图

时间:2013-06-12 01:11:06

标签: objective-c uiview

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

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

我认为在两者之间共享iVar很简单。我在myPoint界面中使用@property创建了一个iVar ViewController(如果这仍然被视为iVar),请在我myPoint = sliderValue.value的{​​{1}}实现中设置ViewController {1}}用于滑块值更改时的值。然后在我的IBAction实施中SecondView然后在#import "ViewController.h"实施中调用我的iVar调用,但按照我的方式执行它只会返回SecondViewnil而不是滑块值。

我不想使用全局变量。

我看过其他一些似乎在问类似问题的帖子,但我还是错过了这个概念。我的代码如下。

ViewController.h

0

ViewController.m

#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

SecondView.h

#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

SecondView.m

#import <UIKit/UIKit.h>

@interface SecondView : UIView

@property (assign, nonatomic) CGFloat thePoint;

@end

2 个答案:

答案 0 :(得分:2)

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

您正在分配一个新的viewController,这个viewController当然不知道您在viewController中设置的实际更改滑块的值。
这不行。这两个viewControllers不是同一个实例。他们共享同一个班级,但就是这样。来自一个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];
}

并在滑块操作

中设置辅助视图的point属性
- (IBAction)sliderChanged:(id)sender
{
    secondView.point = sliderValue.value;
    [secondView setNeedsDisplay];         // you might be able to omit that

    myLabel.text = [NSString stringWithFormat:@"%.2f", myPoint];
}

答案 1 :(得分:-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。您可以选择如何解决此问题。最干净的方法可能是从SecondView中删除#import ViewController.h而不是相反。也就是说,让ViewController执行#import SecondView.h,然后将myView提升为SecondView。

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

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

或者,你可以将滑块的动作指向myView,就像这个问题的答案对于按钮一样:subclass UIView actions in viewcontroller

与编程一样,有几种可能的解决方案。你可以选择最好的一个。祝你好运!