2013-03-19 4 views
0

기본적으로 위임 프로토콜을 사용하는 UIView의 하위 클래스 (RRView)가 있습니다. RRView는 아웃렛을 통해 대리자 프로토콜뿐만 아니라 델리게이트를 구현하는 뷰 컨트롤러에 연결됩니다.위임 프로토콜/IBOutlet

위임자에게 추가 정보를 요청하는 코드는 다음과 같이 구현됩니다.

- (void)setDelegate:(id<RRViewDelegate>)delegate { 
    if (_delegate != delegate) { 
    _delegate = delegate; 

    if (_delegate && [_delegate respondsToSelector:@selector(cornersForRRView:)]) { 
     self.corners = [_delegate cornersForRRView:self]; 
    } 

    if (_delegate && [_delegate respondsToSelector:@selector(cornerRadiusForRRView:)]) { 
     CGFloat maxRadius = floorf(self.bounds.size.height/2); 
     CGFloat radius = [_delegate cornerRadiusForRRView:self]; 
     self.cornerRadius = MIN(radius, maxRadius); 
    } 

    if (_delegate && [_delegate respondsToSelector:@selector(rotationTypeForRRView:)]) { 
     self.type = [_delegate rotationTypeForRRView:self]; 
    } 

    if (_delegate && [_delegate respondsToSelector:@selector(fontSizeForRRView:)]) { 
     self.fontSize = [_delegate fontSizeForRRView:self]; 
     self.textFont = [UIFont fontWithName:self.textFont.fontName size:self.fontSize]; 
    } 
    } 
} 

내가 직면 문제는 내가 그래서 난과 같이 구별하려고 노력하지만, 콘센트가 아직 연결되지 않은 RRViews의 무리를 가지고있다. 이 작업을 수행하는 또 다른 방법은

- (UIRectCorner)cornersForRRView:(RRView *)view { 
    if ([view isEqual:self.dimensionsInfoView]) { 
    return UIRectCornerTopLeft | UIRectCornerTopRight; 
    } 
    else if ([view isEqual:self.oneHundredPercentInfoView]) { 
    return UIRectCornerTopRight; 
    } 
    else if ([view isEqual:self.deviceApperanceInfoView]) { 
    return UIRectCornerTopLeft; 
    } 
    else { 
    return 0; 
} 

}

있습니까?

+0

델리게이트 콜백 메소드에서, if 문은 기본적으로 모두 self.outletVars가 연결되어 있지 않기 때문에 if ([view isEqual : nil])입니다. 그렇다면 코드가 연결되기 전에 코드를 실행하는 문제가 있습니다 ('init :'vs'viewDidLoad') 또는 다른 이유가 있습니까? –

+0

모든 것이 IB에서 이루어지기 때문에 그것은 오히려 질서의 문제입니다. 나는 콘센트를 연결할 때 초기화가 계층 구조를 따라 잡을 것이라고 생각한다. –

답변

0

먼저 포인터 비교를 대신 view == self.dimensionsInfoView으로 안전하게 사용할 수 있습니다. 참조에 동일한 객체가 있는지 확인하고 객체의 내부 상태를 확인하지 않으려합니다. 대리인이 nil (_delegate &&) 인 경우

또한, 확인하지 않아도, 이것은 단지 NO를 반환합니다 nil 위임에 메소드를 호출하는 자바 없습니다.

질문에 대한 답변은 다소 간단합니다.

옵션 1 :IBOutlets이 이미 연결되어있을 때 xib에서 대리인을 설정하지 말고 컨트롤러의 viewDidLoad에서 설정하십시오.

옵션 2 :setDelegate에서 대리자 메서드를 호출하지 말고 다른 방법으로 호출하십시오. [UIView layoutSubviews].

옵션 3 : 대리인의 설정 방법을 삭제하고 viewDidLoad으로 직접 호출하십시오. [self.dimensionsInfoView setFontSize:10.0f], [self.dimensionsInfoView setCorners:... withRadius:...];

나는 확실히 옵션 3과 함께 갈 것이다. 당신은 단지 대리인과의 문제를 복잡하게 만든다. 왜 변하지 않는 무언가를위한 델리게이트 메소드를 호출할까요?

+0

옵션 3은 내가 전에 한 일이었습니다. RRView가 다기능 ... 시간이 지남에 따라 커지면서 더 많은 사용자 정의 기능을 찾고있었습니다. 많은 기능을 갖춘 야수였습니다. 다른 모든 힌트도 주셔서 감사합니다. 최선의 방법은 대리자 호출을 만드는 RRView에서 일반 설정 방법을 사용하는 것입니다. 이렇게하면 초기화가 수행되어야 할 때를 제어 할 수 있으며 위임을 유지할 수 있습니다. –

+0

@BerndRabe 옵션 3 - 단순성을 고수해야하는 이유가 있습니다. 위임자를 사용하여 뷰를 설정하는 것은 이상하고 이점이 없습니다. 이 방법으로 설정된 'UIButton'을 상상해보십시오. 글꼴, 텍스트 및 이미지를 반환하는 대리자 메서드가 있습니다. 많은 위임 방법으로 배포하는 대신 일을 한 곳에 보관하십시오. – Sulthan

+0

전적으로 동의합니다. 옵션 3은 오류가 발생하기 쉬운 오류가 가장 적은 옵션입니다.비록 더 많은 코드를 작성해야하는 곳이긴하지만 (제 경우와 같이, 앵커 포인트를 회전시키고 레이어 테두리 색상을 형성 할 수있는 곳 등). 두 가지 방법을 모두 구현 했으므로 이제 옵션을 사용할 수있게되었습니다. –