0

ViewController 클래스와 View 클래스가 있습니다. ViewController에는 UIScrollView가 있고 View에는 UITableView가 있으며 두 가지 모두 UIScrollViewDelegate의 대리자입니다.위임 메서드의 두 구현에서 코드 중복 제거

View 및 ViewController 모두 scrollViewDidScroll: 대리자 메서드를 사용하며 둘 다 동일한 코드를 사용합니다. 그것은 분명히 중복되므로이 문제를 해결하고 싶습니다.

문제는 어떻게되는지 잘 모릅니다.

기본 클래스에 기능을 추출 할 수 없으며 메서드를 구현하는 클래스를 별도로 가질 수 있다고 생각합니다. 인스턴스를 사용할 수 있습니다 (Android에서는 가능하지만 iOS에서는 사용할 수 없음). 블록을 사용하려고 생각했지만 어떻게 작동하는지 보지 못했습니다.

메소드 자체가 ViewController/View의 UI에서 일부 변경을 수행합니다. 여기에 몸의 :

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 

    float multiplierYAnimationStop = [Utilities getFloatValueFromPlistFile:@"layout_values" forDictionaryKey:@"scroll_background_y_stop_multiplier"]; 
    float currentScrollOffsetY = scrollView.contentOffset.y; 

    // No case for further back than the bottom of the screen (lower than 0) 
    // and if it's higher than where it should stop, keep it at that point 
    if (currentScrollOffsetY > screenHeight * multiplierYAnimationStop) { 

     currentScrollOffsetY = screenHeight * multiplierYAnimationStop; 
    } 

    // Scale the background 
    float newBackgroundScale = 1 - currentScrollOffsetY/screenHeight; 

    if (newBackgroundScale < 0.75f) { 

     newBackgroundScale = 0.75f; 
    } 

    [self scaleBackgroundToNewScale:newBackgroundScale]; 

    // Move the UILabel with the title and the Button 
    float newLabelCenterY = originalLabelTitleCentreY - currentScrollOffsetY; 
    float newButtonCenterY = originalButtonDownArrowCentreY - currentScrollOffsetY; 
    self.labelHeadline.center = CGPointMake(self.labelHeadline.center.x, newLabelCenterY); 
    self.buttonDownArrow.center = CGPointMake(self.buttonDownArrow.center.x, newButtonCenterY); 

    // Blur the UILabel with the title and the Button 
    float newHeadlineAlpha = 1 - currentScrollOffsetY/100.0f; 

    if (newHeadlineAlpha < 0.0f) { 

     newHeadlineAlpha = 0.0f; 
    } 

    [self.labelHeadline setAlpha:newHeadlineAlpha]; 
    [self.buttonDownArrow setAlpha:newHeadlineAlpha]; 

    if (newHeadlineAlpha < 0.95f) { 

     [self.buttonDownArrow setEnabled:NO]; 
    } 
    else { 

     [self.buttonDownArrow setEnabled:YES]; 
    } 

    // Set the new alpha for the background overlay 
    // (no bigger than scroll_overlay_max_opacity, should be scroll_overlay_max_opacity once the offset hits the stop point) 
    float maxOpacity = [Utilities getFloatValueFromPlistFile:@"layout_values" forDictionaryKey:@"scroll_overlay_max_opacity"]; 
    float subtractionFactor = 1.0f - maxOpacity; 

    float newOverlayAlpha = currentScrollOffsetY/screenHeight/multiplierYAnimationStop - subtractionFactor; 

    if (newOverlayAlpha > maxOpacity) { 

     newOverlayAlpha = maxOpacity; 
    } 

    [self.viewOverlay setAlpha:newOverlayAlpha]; 

    // If set, move the background vertically on scroll 
    if ([Utilities getBoolValueFromPlistFile:@"layout_values" forDictionaryKey:@"is_scroll_background_movable"]) { 

     if (newBackgroundScale == 0.75f) { 

      self.imageBackground.center = CGPointMake(self.imageBackground.center.x, self.imageBackground.center.y - (currentScrollOffsetY - 0.25f * screenHeight)); 
     } 
    } 
} 

답변

1

당신이 원하는 캡슐화하는 함수를 만들고 여기에 (아마도 self 포함)에 필요한 변수를 전달합니다.

개체간에 더 많은 중복 논리가있는 경우 두 개체의 인스턴스가 (상속하지 않고)있는 전략 개체로 끌어 올 수 있습니다. 본질적으로 이는 위임자의 위임자가됩니다 (괜찮습니다). 또는 관련 공유 함수 모음이있는 경우 일부 전략 클래스의 클래스 메서드로 만들 수 있습니다. 그러나이 방법과 같은 단 하나의 방법이라면 함수가 좋습니다.

+0

다시 한 번 해결책이 너무 단순하지만 아직 그것에 대해 생각하지 않았습니다! 나는 오늘 오후에 문제를 게시해서는 안되지만 내 문제 때문에 잠을 자고 아침에 물어보십시오.] 감사합니다. – JakeP

0

나는이 목표를 달성하기 위해 별도의 클래스를 사용하는 방법을 알아보기 위해 아래 관련 코드를 포함 시켰습니다.

@interface MyScrollDelegate : NSObject <UIScrollViewDelegate> 
@property (weak) id originalSelf; 
@end 

@interface MyViewController 
@property (strong) MyScrollDelegate *aScrollDelegate; 
@end 

@interface MyView 
@property (strong) MyScrollDelegate *aScrollDelegate; 
@end 

@implementation MyViewController 
- (void)loadView { 
    self.aScrollDelegate.originalSelf = self; 
    myScrollView.setDelegate = self.aScrollDelegate; 
} 
@end 

@implementation MyView 
- (instancetype)init { 
    self.aScrollDelegate.originalSelf = self; 
    myScrollView.setDelegate = self.aScrollDelegate; 
} 
@end