尝试使用自定义类将值传递给UIView时,UISlider值为零

时间:2013-05-21 04:31:51

标签: ios objective-c cocoa-touch uiview

我的UIView文件中UILabel放置了UISliderUIVeiwControllerViewController。我还以编程方式将UILabel添加到UIView作为调试工具。

是的,我可以连接到UILabel中的UIView,就像我对另一个UILabel一样,但是一旦我解决了这个问题,我就会在图中传递这个值计算。我对将此变量传递给UIView的任何建议持开放态度,但我更愿意避免创建全局变量。我将UISlider值传递给我UILabel中的UIVeiwController,但是当我尝试通过“引用”滑块时发送值时我的GraphView.m实现文件中的值永远不会成功,我的值为零。

我花了两天时间搜索stackoverflow论坛,查看文档,重新阅读书籍试图弄清楚我的问题,虽然我学到了很多东西(并修复了其他问题)但我还是没想到这个出。我确信它的东西如此简单,我肯定会踢自己。我欢迎您参考其他文档(我可能已经阅读过)但请提供一些建设性的反馈和指导。我的代码如下:

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    NSString *viewControllerSliderValue;
}
- (NSString *) viewConrtollerSliderValue;

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

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

- (IBAction)sliderChange:(UISlider *)sender;

@end

ViewController.m

#import "ViewController.h"
#import "GraphView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    float sliderVal = self.sliderValue.value;
    self.sliderValueLabel.text = [NSString stringWithFormat:@"%.1f",sliderVal];
    NSLog(@"viewDidLoad: sliderVal = %f", sliderVal);
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)sliderChange:(UISlider *)sender
{
    float sliderVal = sender.value;
    self.sliderValueLabel.text = [NSString stringWithFormat:@"%.1f", sliderVal];
    NSLog(@"sliderChange: sliderVal = %f", sliderVal);

}

- (NSString *)viewConrtollerSliderValue
{
    float sliderVal = self.sliderValue.value;
    viewControllerSliderValue = [NSString stringWithFormat:@"%f",[self sliderValue].value];
    NSLog(@"sliderChange: sliderVal = %f", sliderVal);
    return viewControllerSliderValue;
}

@end

GraphView.h

#import <UIKit/UIKit.h>

@interface GraphView : UIView

@end

GraphView.m

#import "GraphView.h"
#import "ViewController.h"

@implementation GraphView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    ViewController *viewController = [[ViewController alloc] init];

    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 90, 140, 20)];
    NSLog(@"GraphView: drawRect: vierContrllerSliderValue = %@", [viewController viewConrtollerSliderValue]);
    myLabel.text = [viewController viewConrtollerSliderValue];
    myLabel.backgroundColor = [UIColor lightGrayColor];
    myLabel.textAlignment = NSTextAlignmentCenter;
    [self addSubview:myLabel];
}

@end

2 个答案:

答案 0 :(得分:1)

问题是您的GraphView在调用ViewController *viewController = [[ViewController alloc] init];时会创建一个新的视图控制器,该控制器与屏幕上显示的视图控制器不同。新控制器的滑块不是您正在操作的滑块,因此它永远不会改变值。

另一个问题是,每次致电GraphView时,您的drawRect:都会添加新标签。每次需要重新绘制视图时都会调用该方法。相反,在-initWithFrame:方法中将标签添加为子视图,并将其作为实例变量或属性保持对它的引用。

GraphView最好永远不知道视图控制器。相反,GraphView应该只有一个setter方法来设置应该显示的值。当滑块改变时,控制器应负责告知图形视图更新。它看起来像这样:

@interface GraphView
@property (nonatomic) float graphValue;
@end

@implementation GraphView {
    UILabel *graphLabel;
}


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        graphLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 90, 140, 20)];
        graphLabel.backgroundColor = [UIColor lightGrayColor];
        graphLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:graphLabel];
    }
    return self;
}


- (void)setGraphValue:(float)theValue {
    _graphValue = theValue;
    graphLabel.text = [NSString stringWithFormat:@"%f", theValue]
}

// Note; no need for -drawRect, because it will all be drawn by the label, which is a subview.

@end

答案 1 :(得分:0)

我在你的代码中注意到的一些事情:

  • drawRect:方法中的所有内容都应该永远drawRect:中完成。 drawRect:用于在屏幕上绘制像素(使用贝塞尔曲线路径,颜色等)。 drawRect:每秒可以调用很多次,因此尽可能快地调用它是很重要的。因此,永远不应该创建对象和操纵视图层次结构。在drawRect:中创建ViewControllers应该从不完成。

如果您需要设置初始视图状态,那么应该在视图控制器的viewDidLoad方法中完成。您可能希望在xib中创建GraphView并创建与视图控制器的插座连接。您可以通过向xib添加新的UIView并在右侧边栏的Identity检查器中编辑Class来完成此操作,如下所示。 (您也可以使用initWithFrame:以编程方式创建GraphView,并将其添加为视图控制器视图的子视图)

enter image description here