2010-02-05 51 views
1

如果不使用Interface builder或xib文件,實例化從UIView繼承的兩個類的正確方法是什麼,以便它們可以使用位於視圖本身上的UIButton進行切換?如何實例化並調用UIView子類而不使用Nib

我覺得這涉及到從應用程序的委託建立一個UIViewController並加入我的課的兩個實例,它們實現的UIView到控制器(從控制器裏面吧?)

我也不能確定如何提高來自UIButtons的自定義UIViews切換視圖的事件。我懷疑我需要添加一個方法到視圖控制器,但我不知道如何從我的UIView範圍內獲得對視圖控制器的引用。

另外,我想知道,如果需要使用UIViewController,切換方法應該在主應用程序委託的範圍內嗎?

一些代碼示例會很棒!

回答

4

如果你想在代碼中完成它,下面是一個例子,我只是使用惰性加載的UI元素來鼓掌。我只在這裏製作一個按鈕,並在任何一個視圖處於活動狀態之間進行交換。這有點尷尬,但它減少了證明這一點所需的代碼量。

我已經創建了兩個UIViews來表示您的自定義類,其中一個具有藍色背景,另一個具有紅色。按鈕在兩者之間交換。如果每個自定義視圖中都有一個唯一的按鈕,則只需將這些按鈕公開爲UIView子類的屬性,以便您的視圖控制器可以訪問它們,或將視圖控制器添加爲內部按鈕操作的目標你的UIView的加載代碼。

我已經在我的模擬器中測試了這段代碼,它似乎工作正常,但是您應該嘗試瞭解這裏發生了什麼,以便您可以自己實現它。

ToggleViewController.h:

#import <UIKit/UIKit.h> 
@interface ToggleViewController : UIViewController { 
    UIView *firstView; 
    UIView *secondView; 
    UIButton *button; 
} 
- (void)addButton; 
- (void)toggleViews; 
@property (nonatomic, readonly) UIView* firstView; 
@property (nonatomic, readonly) UIView* secondView; 
@property (nonatomic, readonly) UIButton* button; 
@end 

ToggleViewController.m:

#import "ToggleViewController.h" 
@implementation ToggleViewController 

// assign view to view controller 
- (void)loadView { 
    self.view = self.firstView; 
} 

// make sure button is added when view is shown 
- (void)viewWillAppear:(BOOL)animated { 
    [self addButton]; 

} 

// add the button to the center of the view 
- (void)addButton { 
    [self.view addSubview:self.button]; 
    button.frame = CGRectMake(0,0,150,44); 
    button.center = self.view.center; 
} 

// to toggle views, remove button from old view, swap views, then add button again 
- (void)toggleViews { 
    [self.button removeFromSuperview]; 
    self.view = (self.view == self.firstView) ? self.secondView : self.firstView; 
    [self addButton]; 
} 

// generate first view on access 
- (UIView *)firstView { 
    if (firstView == nil) { 
     firstView = [[UIView alloc] initWithFrame:CGRectZero]; 
     firstView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
     firstView.backgroundColor = [UIColor redColor]; 
    } 
    return firstView; 
} 

// generate second view on access 
- (UIView *)secondView { 
    if (secondView == nil) { 
     secondView = [[UIView alloc] initWithFrame:CGRectZero]; 
     secondView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
     secondView.backgroundColor = [UIColor blueColor]; 
    } 
    return secondView; 
} 

// generate button on access 
- (UIButton *)button { 
    if (button == nil) { 

     // create button 
     button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain]; 

     // set title 
     [button setTitle:@"Toggle Views" 
       forState:UIControlStateNormal]; 

     // set self as a target for the "touch up inside" event of the button 
     [button addTarget:self 
        action:@selector(toggleViews) 
     forControlEvents:UIControlEventTouchUpInside]; 
    } 
    return button; 
} 

// clean up 
- (void)dealloc { 
    [button release]; 
    [secondView release]; 
    [firstView release]; 
    [super dealloc]; 
} 

@end 
+0

@Victorb感謝這是偉大的東西。順便說一句,我不得不使用initWithFrame:[[UIScreen mainScreen] applicationFrame]我的firstView方法而不是CGRectZero讓它在模擬器中工作任何想法爲什麼? – PeanutPower

+0

在我的測試中,我將VC添加到標籤欄控制器,以便框架已經建立。我的猜測是,無論你使用什麼容器都沒有正確的框架集。自設置autoresizingMask後,CGRectZero框架應在超級視圖中進行更改。但是如果你的框架能夠按照你的方式工作,那就去吧。 – VictorB

-2

使用Interface Builder。這是有原因的。

+4

公平地說,避免Interface Builder有很多原因。如果我可以幫助它,我自己就不會使用它,並且知道其他開發者也會有同樣的感受。有一點可以說是讓代碼中的所有應用行爲都用於開發和調試。 – VictorB

7

你的主要問題是,你不明白概念與UIViewControllers的UIViews作用。大多數人不會在剛開始時。

視圖是愚蠢的,理想情況下,它們應該由通用對象組成。它們幾乎不包含接口的邏輯。他們不知道或關心其他觀點的存在。您在視圖中放置的唯一邏輯是與視圖本身的即時和泛型功能相關的邏輯,而不管它顯示的數據或應用程序其他部分的狀態如何。你很少需要繼承UIView。這就是爲什麼可以在沒有任何代碼的情況下在界面構建器中完全配置視圖

ViewControllers包含接口的邏輯並將接口連接到數據(但它們不包含或邏輯操作數據。)它們是「智能」且高度自定義的。 viewControllers確實瞭解應用程序上下文中視圖的位置。 viewControllers從nib或以編程方式加載和配置視圖。 viewControllers控制何時顯示或隱藏視圖以及它的順序。 viewControllers確定響應事件採取的操作以及在哪裏顯示哪些數據。

VictorB的示例代碼顯示瞭如何以實用的方式完成這一切。重要的是要注意viewController和view是完全獨立的兩個完全獨立的類。沒有重疊,也沒有必要繼承UIView。所有的定製都在控制器中。

所有這些都是因爲MVC設計模式。它將接口從數據模型中分離出來,使它們都是模塊化的,彼此獨立。這使得每個獨立模塊的設計,調試和重用變得容易。

+0

@TechZen是否意味着我不應該繼承UIView並在其中實現自定義核心圖形的正確代碼?想象一下,例如國際象棋遊戲板的場景和另一種說菜單屏幕的觀點。板繪圖代碼是否屬於UIViewController? – PeanutPower

+0

其實繪製視圖是視圖的一部分,應該在那裏實現。決定畫什麼,畫多少等應該是視圖控制器傳遞數據模型中的數據的功能。在國際象棋遊戲的情況下,你可能在視圖中有一個自定義的繪製方法來處理實際的棋盤本身,但棋子和它們的位置將是視圖控制器和數據模型的責任。意見應儘可能通用,儘可能少。例如,如果你有一個提出棋盤遊戲的視圖,你應該可以在棋盤遊戲中使用它。 – TechZen

相關問題