2011-02-18 66 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)。