2012-06-03 5 views
10

question과 유사하지만 일반 솔루션이나 디자인 패턴 또는 프레임 워크를 찾고 있습니다.iOS에서 UI 컨트롤의 상태 관리를위한 디자인 패턴

Q. 기존 컨트롤의 클래스를 다시 작성할 필요없이 내 iOS 앱의 모든 UI 컨트롤에 상태 관리를 자동으로 추가하는 방법은 무엇입니까?

예 :

예컨대 UIButton을 클릭하면 Google 홈 페이지를 표시하는 새로운 UIWebView이 생성됩니다. 간단하지만 문제가 발생할 때가 있습니다. 사용자가 가끔씩 버튼을 클릭하면 두 개의 webview가 표시됩니다.

이 질문을 해결하려면 webview를 포함하는 싱글 톤 클래스를 만들고 상태 변수 isOpended이 있어야하며, 이것이 사실이라면 새로운 웹 뷰를 만드는 대신 기존 웹 뷰를 재사용하십시오.

하지만 문제는 다음과 같습니다. 다른 컨트롤에서도이 동작을 원한다면, 많은 싱글 톤 클래스를 만들어야합니다. 새로운 것을 수정하지 않고 더 좋은 방법으로 처리한다면 더 좋은 방법이 될 것이라고 생각합니다. 바퀴.

감사합니다.

+0

답이 맞지 않기 때문에이 문제에 다르게 접근해야합니다. 기록을 위해, 이것을하기위한 아주 쉬운 방법은 연관 참조를 사용하여 속성을 추가하는 UIControl의 카테고리를 작성하는 것입니다. 당신이 비 객체와 연관 참조를 사용할 수 있는지 확신 할 수 없지만 skeleton NSObject 서브 클래스가 적절히 typedef 된 것은 같은 목적을 달성 할 것입니다. 주제를 벗어난 – Swizzlr

답변

10

여기에 잘못된 문제를 해결하고 있다고 생각합니다. UIWebView 처리가 완료 될 때까지 버튼을 비활성화하지 않는 이유는 무엇입니까? 그렇게하면 사용자는 두 번 클릭 할 수 없습니다.

- (IBAction)showMapHomepage:(UIButton*)sender 
{ 
    sender.enabled = NO; 
    [self taskThatTakesALongTimeWithCompletion:^{ 
     sender.enabled = YES; 
     // Finish processing 
    }]; 
} 
+0

: 단추를 __block var로 정의해야합니다. – CarlJ

+0

왜? 코드가 정상적으로 작동한다고 생각합니다. – zoul

+0

@meccan 발신자가 __block이어야한다고 생각하는 이유가 확실하지 않습니다. 나는 포인터를 바꿀 필요가 없으므로 const로 좋다. 표준 블록 규칙은 자동으로 올바르게 유지/해제됩니다. 올바른 코드입니다. –

4

문제를 해결하는 가장 좋은 방법을 오해하고 있습니다. 무엇보다도 많은 싱글 톤을 만드는 상황에서 자신을 발견해서는 안됩니다. 싱글 톤은 필요한 악이며, 너무 많이 사용하거나 남용해서는 안됩니다. objective-c의 싱글 톤에 대해 Here is a good post

사용자가 단추를 클릭 할 때 두 번째 UIWebView가 표시되지 않도록 할 수있는 방법은 다양합니다.

다른 사람이 말했듯이 한 가지 해결책은 버튼을 비활성화하여 사용자가 "두 번 클릭"할 수 없게하는 것입니다. 당신의있는 UIButton를 포함하는 클래스의 헤더에, 당신은 논리를 처리 할 부울을 만들 수

button.hidden = YES; 

을 또는 :

button.enabled = NO; 

또한 사용하여 버튼을 숨길 수 :이 사용 할 버튼이 눌려 졌는지의 여부;

// declare this in your header 
BOOL buttonPressed; 

// this is the IBAction that your button hooks up to 
- (IBAction)createWebViewButtonPressed:(id)sender { 
    if(!buttonPressed) { 
     buttonPressed = YES; 
     // insert code here to create your UIWebView 
    } 
} 

다시 말해서 수행하려는 작업을 수행 할 수있는 다양한 방법이 있습니다. 어떤 방법이 가장 적합한 지 결정해야합니다.

+0

또한, "권장"하지 않더라도 함수 내에서 정적 변수로 buttonPressed var을 선언하면 더 깨끗하다고 ​​생각합니다. 이렇게하면 모든 기능에 동일한 이름을 사용할 수 있습니다. – Raspu

4

컨트롤을 두 번 활성화하지 않으려면 컨트롤을 사용하지 않도록 설정해야한다는 다른 답변에 동의합니다. 그러나 모든 컨트롤에 사용할 수있는 제네릭 패턴에 대한 실제 질문에 대한 대답을 원한다면 관련 개체를 사용할 수 있습니다.

- (IBAction)buttonAction:(UIButton*)sender 
{ 
    NSString* webViewKey = @"AssociatedWebView"; 
    // See if there is web view already 
    id webView = objc_getAssociatedObject(sender, webViewKey); 
    if(webView == nil) 
    { 
     // There is no existing web view, create it 
     webView = [self theWebView]; 
     // Associate it with the button 
     objc_setAssociatedObject(sender, webViewKey, webView, OBJC_ASSOCIATION_RETAIN); 
     // Add the web view 
     [self.view addSubview:webView]; 
    } 
} 

는 위의 이미 관련 기존 하나를 재 - 사용하는 경우 그래서 당신은 확인할 수 UIButton의 인스턴스에 객체를 연결하는 일반적인 방법을 보여줍니다. 귀하의 질문에 완전히 설명되지 않은 다른 방법으로 이것을 사용하려는 경우이 대답을 제공하지만 실제적으로 컨트롤러의 속성을 webView에 사용하면 webView을 느리게로드합니다. 이미로드되었습니다.

당신이 정말은 (모든이 이미 존재하는 경우 같은 webView 객체를 공유하는 많은 UIButton 인스턴스를 가질 수 있도록) 당신이 당신의 질문에 대해 논의 싱글 스타일을 시뮬레이션 할 경우에 당신이 상 webView를 연결할 수 [UIButton class] 개체 또는 특정 인스턴스 대신 [UIControl class] 개체 일 수도 있습니다. 위의 코드에서 sender[UIControl class]으로 바꾸면됩니다.

3

하나의 가능한 솔루션은 viewController의 속성에 webview에 대한 포인터를 저장하는 것입니다. 이미 존재하지 않으면 webview에 대한 getter에서 webview를 만듭니다. 버튼 동작은 이미 존재하는 경우 webview를 다시 표시하기 때문에 webview를 표시해야하며 그렇지 않은 경우 webview를 만듭니다. webview를 끝내면, 그냥 nil로 설정하십시오.