簡體   English   中英

UIView和UIViewController

[英]UIView and UIViewController

我知道這確實是基本知識,但是我需要了解我對此的理解是否正確。

所以我想做的就是這個。 我想要一個帶有標簽的視圖,雙擊該標簽可以翻轉並加載另一個視圖。 在第二個視圖上,我想要一個UIPickerView ,上面有一個按鈕說回來。 這兩個視圖的大小將與UIPickerView大小相同,為320px x 216px。

我正在考慮做的是創建兩個名為labelView和pickerView的UIView類。 然后,我將創建一個viewController ,它在loadView加載labelView然后當用戶雙擊labelView我在labelView類中得到一個事件,該事件發送到我的viewController ,然后可以卸載loadView並加載pickerView

聽起來這是最好的方法嗎? 有沒有更簡單的方法? 我也不確定如何將事件從labelView類路由到viewController類。

要將事件從按鈕發送到視圖控制器,只需使用界面生成器將按鈕的事件(例如在內部觸摸)連接到視圖控制器中的方法。 (不過,雙擊可能會更復雜。)

當您說“翻轉”時,您是說它實際上顯示了一個翻轉視圖以顯示“反面”的動畫嗎? 就像在按下“ i”按鈕時在天氣應用中一樣? 我假設這就是你的意思。

也許在iPhone參考資料庫中查看TheElements示例示例,它有一個翻轉動畫的示例。

順便說一句,並非絕對必要在翻轉時卸載被“隱藏”的loadView -節省了您在翻轉時必須再次構造的loadView -但如果您有內存使用方面的顧慮,和/或系統警告您內存不足。

另外,“創建UIView”是什么意思? 您是指UIView的子類,還是僅實例化UIVIew並向其添加子視圖對象? 后者是通常的策略。 不要僅僅因為要向UIView添加一些東西而對UIView進行子類化。

我不完全知道最有效的方法(因為我現在也使用這種語言),但是可以肯定的是我已經解決了您的問題。 我為此編寫了一個簡單的程序。例如,這里涉及的三個類是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];
}

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

在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;
}

如果您有一屏信息讓位給另一屏信息,通常可以將它們分開設置為視圖控制器。 因此,在您的情況下,您將擁有一個帶有標簽的視圖控制器,並且在收到所需輸入后,將切換到由UIPickerView和按鈕組成的視圖控制器。

假設您使用Interface Builder,則可能會有一個頂級XIB(通常的項目模板將提供),它定義了應用程序委托,並在單獨的XIB(也提供)中包含了對初始視圖控制器的引用。 在單獨的XIB中,您可能希望通過引用添加另一個視圖控制器(因此,將其放入,為其提供類名,但指示其描述包含在另一個文件中),然后在該視圖控制器中將其放置在選擇器視圖中,按鈕。

與普通的類init分開,loadView的目的是便於命名和鏈接到一個XIB中的實例,同時在另一個XIB中定義布局。 當分配了對視圖控制器的引用並將其初始化時,便會分配並初始化視圖控制器。 但是視圖僅在將要呈現時才加載,並且可能在應用程序運行時被卸載和重新加載(盡管在顯示時未加載)。 一般而言,將在需要時加載視圖,而在內存不足警告時將卸載不必要的視圖。 即使您沒有在XIB中放任何東西,而只是在loadView中以編程方式創建視圖或作為viewDidLoad的結果,這都是自動的。

我已經說了所有這些都比您的解決方案復雜,但實際上它更簡單,因為一旦您不了解它,就可以在Interface Builder中完成很多工作。 實際上,可能值得直接跳到Xcode 4 beta,因為它在該領域動搖了很多事情,而且據網站報道,曾有一位種子大師獲得了種子,因此很可能很快就成為正式事情。

關於捕獲雙擊,最簡單的方法是UITapGestureRecognizer (請參閱此處 )。 您將執行以下操作:

// 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)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM