2014-02-11 56 views
0

我想了解Objective-C在iOS應用中MVC模式的實現。UIView中的IBAction - 與MVC兼容?

現在我有一個DataProvider對象,它保存我的數據並將其提供給我的應用程序(模型)中的其他對象。此外,我有一個視圖(.xib)和一個額外的類(UIView;我們稱之爲「ViewClass」)。我告訴我的觀點是我的ViewClass的一個子類,這樣我就可以創建IBOutlet到我的子視圖,如標籤和IBAction s到我的按鈕。所以這顯然是我在MVC模式中的視圖。

最後但並非最不重要的一點,我有一個ViewController對象,它引用了我的DataProvider並保存了View的一個對象。當ViewController加載到內存中時,它通過viewDidLoad實例化視圖,並通過調用addSubview:(UIView *)view將其添加到其自己的視圖中。這是我在MVC模式中的控制器。

到目前爲止好,但我不明白的是以下。根據MCV-Pattern,視圖應僅顯示由ViewController提供的數據,該數據從模型中獲取數據。任何邏輯操作只應發生在ViewController,因爲它負責這類任務。 但是,如果我在我的「ViewClass」中創建IBAction,我不得不在我的View中使用某種編程邏輯。

假設我想提交一個表單,其中包含用戶通過單擊按鈕在某個文本框中輸入的數據。在我的ViewClass中,我有一個IBOutlet文本框,以便稍後可以參考它並讀取用戶輸入的數據。我有一個IBAction的按鈕,可以捕捉點擊事件。發送數據的代碼現在寫在我的視圖的IBAction方法中,所以我在我的視圖中有程序邏輯。

我的問題:這不是違反MVC模式?

我可能經過的參考我ViewController我的看法,而我創建視圖的一個實例,然後調用我的ViewController的方法在IBAction然後把它和發送數據。 但我無法真正想象這是正確的做法。或者我理解錯了什麼?

在此先感謝。

+0

我可能還沒有理解你的例子,但你爲什麼不把IBAction放到View Controller?視圖控制器有/應該有權訪問它的所有子視圖(遞歸)。 –

+0

因爲這是不可能的。我只能在我的View(.xib)繼承的「ViewClass」中創建IBAction。 – user3296221

回答

0

不知道我是否正確理解了您的視圖層次結構,但我不建議將屬於該模型的任何邏輯放入視圖中。

我會使ViewClass成爲UIControl的一個子類,以便它自己發送事件。如果按下按鈕,則發送viewController接收到的valueChangedEvent。

e.g:

// .h 
@interface ViewClass : UIControl 
@property (readonly, nonatomic) UIButton *button; // read only in public interface 
@property (readonly, nonatomic) UITextField *textField; 
@end 

// .m 
@interface ViewClass() 
@property (strong, nonatomic) UIButton *button;  // readwrite in private interface 
@property (strong, nonatomic) UITextField *textField; 
@end 

@implementation ViewClass 
- (IBAction)buttonPressed:(UIButton *)sender { 

    // send valueChanged event to target 
    [self sendActionsForControlEvents:UIControlEventValueChanged]; 
} 

@end 

和你的viewController:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    ViewClass *myView = ... 
    [myView addTarget:self action:@selector(myViewDidChangeValue:) forControlEvents:UIControlEventValueChanged]; 
} 

- (IBAction)myViewDidChangeValue:(ViewClass *)sender { 
    NSLog(@"Send \"%@\" to server", sender.textField.text); 
} 

你也可以使用addTarget:forControlEvents:爲視圖的子視圖以及。所以你實際上可以將ViewClass的按鈕連接到你的viewController,你可能無法在Interface Builder中做到這一點。

[myView.button addTarget:self action:@selector(viewButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 
+0

好吧,這似乎是我正在尋找的方法。 – user3296221

+0

也許可以將ViewController註冊爲Observer並在IBAction中通知ViewController,並以此方式調用包含邏輯的Method。你對這個想法有什麼看法? 但我想知道如果這是蘋果想解決這個問題的方式...... – user3296221

+1

有很多種方法可以解決這個問題。如果我想將視圖連接到viewControllers,我通常使用這個目標操作模式,因爲它負擔得起。您可以使用委託,我通常使用它將viewControllers連接到viewControllers,但它們需要@協議,並且通常對於想要發送單個消息的視圖沒有意義。有NSNotifications,我用它將不相關的模型連接在一起。最後但並非最不重要的關鍵價值觀察,我很少使用。但那只是我。你可以嘗試一切。選擇何時是一個巨大的話題本身。 –