2011-02-18 57 views
0

我知道这是非常基本的东西,但我需要了解我对此的理解是否正确。UIView和UIViewController

所以我想要做的是这个。我想要一个带有标签的视图,当双击轻击并加载另一个视图时,该标签就会显示。在第二个视图中,我想要一个UIPickerView或更高版本,我有一个按钮回复。这两个视图的大小将与320px x 216px的UIPickerView大小相同。

我想要做的是创建两个名为labelView和pickerView的UIView类。然后,我将创建一个viewController其上loadView负载labelView那么当用户双击水龙头labelView我得到labelView类的事件被发送到我的viewController那则可以卸载loadView并加载pickerView

这听起来是最好的方法吗?有一种更简单的方法吗?我也不确定如何将事件从labelView类路由到viewController类。

回答

2

我不完全知道最有效的方式来做到这一点(因为我现在也是这种语言),但它是肯定的,我已经解决了你的问题。我为此做了一个简单的程序。在我的例子中涉及的三个类是BaseViewController(它将显示两个视图),LabelView和PickerView(根据您的要求)。

在LabelView.h

@protocol LabelViewDelegate 
-(void)didTapTwiceLabelView; 
@end 

@interface LabelView : UIView { 

id <LabelViewDelegate> delegate; 
} 
@property(nonatomic,retain)id <LabelViewDelegate> delegate; 
-(void)didTouch; 

@end 

在LabelView.m

@synthesize delegate; 

-(id)initWithFrame:(CGRect)frame { 

self = [super initWithFrame:frame]; 
if (self) 
{ 
    UILabel* labl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, frame.size.width-20,20)]; 
    labl.text = @"Some Text"; 
    [self addSubview:labl]; 
    [labl release]; labl = nil; 
    self.backgroundColor = [UIColor grayColor]; 
    UITapGestureRecognizer* ges = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTouch)] autorelease]; 
    ges.numberOfTapsRequired = 2; 
    [self addGestureRecognizer:ges]; 

    } 
    return self; 
} 


-(void)didTouch 
{ 
[delegate didTapTwiceLabelView]; 
} 

// ====================== =======================================

In Pickerview.h

@protocol PickerViewDelegate 
-(void)didTapBackButton; 
@end 

@interface PickerView : UIView <UIPickerViewDelegate,UIPickerViewDataSource>{ 

id <PickerViewDelegate> delegate; 
} 
@property(nonatomic,retain)id <PickerViewDelegate> delegate; 

@end 

在Pickerview.m

@implementation PickerView 

@synthesize delegate; 

-(id)initWithFrame:(CGRect)frame { 

self = [super initWithFrame:frame]; 
if (self) 
{ 
    UIPickerView* picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 30, 320, 216)]; 
    picker.delegate = self; 
    picker.dataSource = self; 
    [self addSubview:picker]; 
    [picker release]; picker = nil; 
    self.frame = CGRectMake(frame.origin.x, frame.origin.y, 320, 250); 

    UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [btn setFrame:CGRectMake(10, 1, 50, 27)]; 
    [btn setTitle:@"Back" forState:UIControlStateNormal]; 
    [btn addTarget:self action:@selector(backButton) forControlEvents:UIControlEventTouchUpInside]; 
    [self addSubview:btn]; 
    } 
    return self; 
} 
-(void)backButton 
{ 
[delegate didTapBackButton]; 
} 

// ==================================== ================================

在BaseViewController.h

#import "LabelView.h" 
#import "PickerView.h" 

@interface VarticalLabel : UIViewController<UITextFieldDelegate,PickerViewDelegate,LabelViewDelegate> { 

PickerView* myPickerView; 
LabelView* myLabelView; 
} 

@end 

在BaseViewController

。 m

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

myPickerView= [[PickerView alloc] initWithFrame:CGRectMake(0, 50, 320, 250)]; 
[self.view addSubview:myPickerView]; 
myPickerView.delegate = self; 

myLabelView= [[LabelView alloc] initWithFrame:CGRectMake(0, 50, 320, 250)]; 
[self.view addSubview:myLabelView]; 
myLabelView.delegate = self; 

myPickerView.hidden = YES; 

} 
#pragma mark PickerViewDelgate 
-(void)didTapBackButton 
{ 
myPickerView.hidden = YES; 
myLabelView.hidden = NO; 
} 

#pragma mark LabelViewDelegate 
-(void)didTapTwiceLabelView 
{ 
myPickerView.hidden = NO; 
myLabelView.hidden = YES; 
} 
2

要将按钮的事件从按钮传递给视图控制器,只需挂上按钮的事件,例如在视图控制器中使用界面构建器触及内部。 (尽管双击可能更复杂。)

当你说'翻转'时,你的意思是它实际上显示了翻转视图以显示'反向'边的动画吗?当你点击'我'按钮时,就像在天气应用程序中一样?我假设这就是你的意思。

也许检查TheElements iPhone参考库的示例示例,它有一个翻转动画的例子。

顺便说一句,当你翻转时,不需要卸载被“隐藏”的loadView - 它可以避免在你翻转时再次构造它 - 但是如果你有内存使用问题,它可能是恰当的,和/或系统警告你内存不足。

另外,你是什么意思的“创建一个UIView”?你的意思是子类UIView,或者只是实例化一个UIVIew并添加子视图对象?后者是通常的策略。不要仅仅因为你想添加一些东西到UIView而继承UIView。

+0

是的,我的意思是和我在地图上一样的动画。我的问题在这里更多,如果应用程序的架构是正确的使用UIView和UIViewController。我不确定是否应该改为创建三个UIViewControllers。 – dbrasco 2011-02-18 11:55:39

+0

Apple对此有一些建议,通常是正确的:对于一个屏幕的东西,有一个UIViewController。尽管苹果在各个地方实际上违反了他们自己的规则(!),但作为'最终用户'程序员,通常这是个好主意。 – occulus 2011-02-18 12:07:42

1

如果您有一个信息屏幕让位于另一个信息屏幕,您通常会让它们成为单独的视图控制器。所以在你的情况下,你将有一个视图控制器和标签,并在收到你想要的输入时,你会切换到由UIPickerView和按钮组成的视图控制器。

假设您使用Interface Builder,您可能会有一个顶层XIB(正常的项目模板将提供)定义应用程序委托并包含对单独XIB(也提供)中的初始视图控制器的引用, 。在单独的XIB中,您可能希望通过引用添加另一个视图控制器(因此,放入它,给它类名称,但表明它的描述包含在另一个文件中),并在该视图控制器放入选择器视图和按钮。

loadView作为独立于普通类init的一点是为了方便命名和链接到一个XIB中的实例,同时在另一个XIB中定义布局。视图控制器被分配和引用,当引用它们的东西被分配和引用时。但该视图只在将要呈现时加载,并且在应用程序运行时可能会卸载并重新加载视图(尽管不会在显示时显示)。一般来说,视图将在需要时加载,而不必要的视图将在低内存警告时卸载。即使您没有在XIB中添加任何内容,并且只是在loadView中或通过viewDidLoad以编程方式创建视图,这全部是自动的。

我已经说过,所有的声音都比你的解决方案复杂得多,但它实际上更简单一些,因为你可以在界面生成器中做的量,一旦你超过了它的学习曲线。实际上,这可能是值得直接跳到Xcode 4测试版的,因为它在这个领域震动了很多,并且网站报道说黄金大师在某一时刻被种下了种子,所以很快就会成为官方的东西。

关于捕捉双击,最简单的事情是UITapGestureRecognizer(请参阅here)。你会做这样的事情:

// create a tap gesture recogniser, tell it to send events to this instance 
// of this class, and to send them via the 'handleGesture:' message, which 
// we'll implement below... 
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] 
          initWithTarget:self action:@selector(handleGesture:)]; 

// we want double taps 
tapGestureRecognizer.numberOfTapsRequired = 2; 

// attach the gesture recogniser to the view we want to catch taps on 
[labelView addGestureRecognizer:tapGestureRecognizer]; 

// we have an owning reference to the recogniser but have now given it to 
// the label. We don't intend to talk to it again without being prompted, 
// so should relinquish ownership 
[tapGestureRecognizer release]; 


/* ... elsewhere ... */ 

// the method we've nominated to receive gesture events 
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer 
{ 
    // could check 'gestureRecognizer' against tapGestureRecognizer above if 
    // we set the same message for multiple recognisers 

    // just make sure we're getting this because the gesture occurred 
    if(gestureRecognizer.state == UIGestureRecognizerStateRecognized) 
    { 
     // do something to present the other view 
    } 
} 

手势识别器可作为iOS 3.2的(这仅是为iPad;等等iPhone和iPod Touch的iOS 4.0)。