简体   繁体   English

UIView和UIViewController

[英]UIView and UIViewController

I know this is really basic stuff but i need to understand whether my understanding of this is correct. 我知道这确实是基本知识,但是我需要了解我对此的理解是否正确。

So what i want to do is this. 所以我想做的就是这个。 I want an view with a label on which when double tapped flips and loads another view. 我想要一个带有标签的视图,双击该标签可以翻转并加载另一个视图。 On the second view i want a UIPickerView and above i have a button saying back. 在第二个视图上,我想要一个UIPickerView ,上面有一个按钮说回来。 Both views will be of same size as an UIPickerView which is 320px x 216px. 这两个视图的大小将与UIPickerView大小相同,为320px x 216px。

What i am thinking of to do is create two UIView classes named labelView and pickerView. 我正在考虑做的是创建两个名为labelView和pickerView的UIView类。 I would then create a viewController which on loadView loads labelView then when user double taps the labelView i get an event in labelView class which is sent to my viewController that then can unload loadView and load the pickerView . 然后,我将创建一个viewController ,它在loadView加载labelView然后当用户双击labelView我在labelView类中得到一个事件,该事件发送到我的viewController ,然后可以卸载loadView并加载pickerView

Does this sound as the best way to do this ? 听起来这是最好的方法吗? Is there a simpler way ? 有没有更简单的方法? I am also unsure how i route the event from the labelView class to the viewController class. 我也不确定如何将事件从labelView类路由到viewController类。

To get events from a button to the view controller, just hook up the button's event, eg touch up inside, to a method in the view controller, using interface builder. 要将事件从按钮发送到视图控制器,只需使用界面生成器将按钮的事件(例如在内部触摸)连接到视图控制器中的方法。 (Double tapping is probably more complicated though.) (不过,双击可能会更复杂。)

When you say 'flips', do you mean it actually shows an animation of flipping over a view to show a 'reverse' side? 当您说“翻转”时,您是说它实际上显示了一个翻转视图以显示“反面”的动画吗? Like in the weather app when you hit the 'i' button? 就像在按下“ i”按钮时在天气应用中一样? I'm assuming this is what you mean. 我假设这就是你的意思。

Perhaps check TheElements sample example on the iPhone Reference Library, it has an example of flip animation. 也许在iPhone参考资料库中查看TheElements示例示例,它有一个翻转动画的示例。

Btw, it's not strictly necessary to unload the loadView that is being 'hidden' when you flip -- it saves you having to construct it again when you flip back -- but it may be pertinent if you have memory use concerns, and/or the system warns you about memory being low. 顺便说一句,并非绝对必要在翻转时卸载被“隐藏”的loadView -节省了您在翻转时必须再次构造的loadView -但如果您有内存使用方面的顾虑,和/或系统警告您内存不足。

Also, what do you mean by "create a UIView"? 另外,“创建UIView”是什么意思? Do you mean subclass UIView, or just instantiate a UIVIew and add children view objects to it? 您是指UIView的子类,还是仅实例化UIVIew并向其添加子视图对象? The latter is the usual strategy. 后者是通常的策略。 Don't subclass UIView just because you want to add some things to a UIView. 不要仅仅因为要向UIView添加一些东西而对UIView进行子类化。

I dont exactly know the most efficient way to do it(as i am also now to this language),but it is for sure that i have solved ur problem. 我不完全知道最有效的方法(因为我现在也使用这种语言),但是可以肯定的是我已经解决了您的问题。 I made a simple program for that.Three classes involved here in my eg are BaseViewController (which will show two views),LabelView and PickerView (according to ur requirement). 我为此编写了一个简单的程序。例如,这里涉及的三个类是BaseViewController(将显示两个视图),LabelView和PickerView(根据您的要求)。

In LabelView.h 在LabelView.h中

@protocol LabelViewDelegate
-(void)didTapTwiceLabelView;
@end

@interface LabelView : UIView {

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

@end

In LabelView.m 在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 在Pickerview.h中

@protocol PickerViewDelegate
-(void)didTapBackButton;
@end

@interface PickerView : UIView <UIPickerViewDelegate,UIPickerViewDataSource>{

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

@end

In Pickerview.m 在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];
}

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

in BaseViewController.h 在BaseViewController.h中

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

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

PickerView* myPickerView;
LabelView* myLabelView;
}

@end

In BaseViewController.m 在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;
}

If you've got one screen of information that gives way to another screen of information, you'd normally make them separate view controllers. 如果您有一屏信息让位给另一屏信息,通常可以将它们分开设置为视图控制器。 So in your case you'd have one view controller with the label and upon receiving the input you want, you'd switch to the view controller composed of the UIPickerView and the button. 因此,在您的情况下,您将拥有一个带有标签的视图控制器,并且在收到所需输入后,将切换到由UIPickerView和按钮组成的视图控制器。

Supposing you use Interface Builder, you would probably have a top level XIB (which the normal project templates will have provided) that defines the app delegate and contains a reference to the initial view controller in a separate XIB (also supplied). 假设您使用Interface Builder,则可能会有一个顶级XIB(通常的项目模板将提供),它定义了应用程序委托,并在单独的XIB(也提供)中包含了对初始视图控制器的引用。 In the separate XIB you'd probably want to add another view controller by reference (so, put it in, give it the class name but indicate that its description is contained in another file) and in that view controller put in the picker view and the button. 在单独的XIB中,您可能希望通过引用添加另一个视图控制器(因此,将其放入,为其提供类名,但指示其描述包含在另一个文件中),然后在该视图控制器中将其放置在选择器视图中,按钮。

The point of loadView, as separate from the normal class init, is to facilitate naming and linking to an instance in one XIB while having the layout defined in another. 与普通的类init分开,loadView的目的是便于命名和链接到一个XIB中的实例,同时在另一个XIB中定义布局。 View controllers are alloced and inited when something that has a reference to them is alloced and inited. 当分配了对视图控制器的引用并将其初始化时,便会分配并初始化视图控制器。 But the view is only loaded when it is going to be presented, and may be unloaded and reloaded while the app is running (though not while it is showing). 但是视图仅在将要呈现时才加载,并且可能在应用程序运行时被卸载和重新加载(尽管在显示时未加载)。 Generally speaking, views will be loaded when needed and unnecessary views will be unloaded upon a low memory warning. 一般而言,将在需要时加载视图,而在内存不足警告时将卸载不必要的视图。 That's all automatic, even if you don't put anything in the XIBs and just create a view programmatically within loadView or as a result of viewDidLoad. 即使您没有在XIB中放任何东西,而只是在loadView中以编程方式创建视图或作为viewDidLoad的结果,这都是自动的。

I've made that all sound more complicated than your solution, but it's actually simpler because of the amount you can do in Interface Builder, once you're past the curve of learning it. 我已经说了所有这些都比您的解决方案复杂,但实际上它更简单,因为一旦您不了解它,就可以在Interface Builder中完成很多工作。 It may actually be worth jumping straight to the Xcode 4 beta, as it shakes things up quite a lot in this area and sites have reported that a gold master was seeded at one point, so is likely to become the official thing very soon. 实际上,可能值得直接跳到Xcode 4 beta,因为它在该领域动摇了很多事情,而且据网站报道,曾有一位种子大师获得了种子,因此很可能很快就成为正式事情。

With respect to catching the double tap, the easiest thing is a UITapGestureRecognizer (see here ). 关于捕获双击,最简单的方法是UITapGestureRecognizer (请参阅此处 )。 You'd do something like: 您将执行以下操作:

// 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
    }
}

Gesture recognisers are available as of iOS 3.2 (which was for iPad only; so iOS 4.0 on iPhone and iPod Touch). 手势识别器自iOS 3.2起可用(仅适用于iPad; iPhone和iPod Touch上为iOS 4.0)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM