2014-02-11 2 views
0

Objective-C를 사용하는 iOS 앱에서 MVC 패턴의 구현을 이해하려고합니다.UIView의 IBAction - MVC와 호환됩니까?

지금은 응용 프로그램 (모델)의 다른 객체에 데이터를 저장하고 제공하는 DataProvider 객체가 있습니다.

추가 클래스 (UIView; "ViewClass"라고 부름)가있는보기 (.xib)가 있습니다. 내 뷰는 내 ViewClass의 하위 클래스가되도록 했으므로 레이블과 IBAction 버튼과 같은 서브 뷰에 IBOutlet을 만들 수 있습니다. 그래서 이것은 MVC-Pattern에서의 나의 뷰입니다.

마지막으로 중요한 것은 내 DataProvider에 대한 참조가 있고 내 View의 개체를 보유하고있는 ViewController 개체입니다. ViewController이 메모리에로드되면 을 호출하여보기를 viewDidLoad에 인스턴스화하고 자체보기에 추가합니다. 이것은 MVC 패턴의 컨트롤러입니다.

지금까지 그렇게 좋았지 만 이해할 수없는 것은 다음과 같습니다. MCV-Pattern에 따르면,보기는 모델에서 데이터를 가져 오는 ViewController에 의해 제공된 데이터 만 표시해야합니다. 이러한 종류의 작업을 담당하는 논리 작업은 ViewController에서만 발생해야합니다. 그러나 "ViewClass"에 IBAction을 만들면 내보기에 일종의 프로그래밍 논리가 있어야합니다.

버튼을 클릭하여 사용자가 텍스트 필드에 입력 한 데이터가있는 양식을 제출하고 싶습니다. 내 ViewClass에서 나는 나중에 그것을 참조하고 사용자가 입력 한 데이터를 읽을 수 있도록 텍스트 필드에 IBOutlet을 가지고 있습니다. 클릭 이벤트를 잡으려면 버튼에 IBAction이 있어야합니다. 이제 데이터를 전송하는 코드가 내보기의 IBAction 방법으로 작성되므로 내보기에 프로그램 논리가 있습니다.

내 질문에 :이 MVC 패턴에 위배 아닌가요?

나는 가능성의 기준을 통과 할 수 내 ViewController 내가보기의 인스턴스를 생성 한 후 다음 얻고 데이터를 전송하는 IBActionViewController의 메소드를 호출하면서 내 볼 수 있습니다. 하지만 이것이 올바른 접근 방식이라고 상상할 수는 없습니다. 아니면 내가 잘못된 것을 이해합니까?

미리 감사드립니다.

+0

예제를 이해하지 못했지만 IBAction을 View Controller에 넣지 않는 이유는 무엇입니까? 뷰 컨트롤러는 모든 하위 뷰 (재귀 적으로)에 액세스 할 수 있어야합니다. –

+0

이것은 가능하지 않기 때문에. 내 View (.xib)가 상속하는 "ViewClass"에서 IBAction 만 만들 수 있습니다. – user3296221

답변

0

뷰 계층을 올바르게 이해할 수 있는지 확실하지 않지만 모델에 속한 논리를 뷰에 배치하지 않는 것이 좋습니다.

ViewClass를 이벤트 자체를 보낼 수 있도록 UIControl의 하위 클래스로 만듭니다. 그리고 버튼이 눌려지면 viewController가받는 valueChangedEvent를 보냅니다.

예컨대 :

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

또한 Observer로 ViewController를 등록하고 IBAction에서 ViewController에 알리고이 방법으로 논리를 포함하는 Method를 호출하는 것이 가능할 수도 있습니다. 이 아이디어에 대해 어떻게 생각하십니까? 그러나이 문제를 해결하는 방법에 대해 Apple이 생각한 방법인지 궁금합니다. – user3296221

+1

해결 방법은 다양합니다. ViewController에 뷰를 연결하려면 일반적으로이 target-action 패턴을 사용합니다. 당신은 viewController를 viewController에 연결하기 위해 보통 사용하는 델리게이트를 사용할 수 있지만 @protocols가 필요하며 보통 단일 메시지를 보내려는 뷰에는 이해가 가지 않습니다. 관련없는 모델을 함께 연결하는 데 사용하는 NSNotifications가 있습니다. 그리고 드물게 중요한 Key-Value-Observation이 있습니다. 하지만 그건 나 뿐이야. 당신은 그들 모두를 시도 할 수 있습니다. 어떤 방법으로 거대한 주제가 언제 선택 될 수 있습니다. –