从委托方法的 2 个实现中删除代码重复
Remove code duplication from 2 implementations of delegate methods
我有一个 ViewController class 和一个视图 class。 ViewController 有一个 UIScrollView,View 有一个 UITableView,两者都是 UIScrollViewDelegate 的委托。
View 和 ViewController 都使用了 scrollViewDidScroll:
委托方法,并且都具有相同的代码。这显然是重复的,所以我想解决这个问题。
问题是我不知道怎么做。
我无法将功能提取到基础 class 中,我也不认为我可以有一个单独的 class 实现该方法,然后我可以使用它的实例(这是可能的在 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));
}
}
}
创建一个函数来封装你想要的东西,并将任何需要的变量(可能包括self
)传递给它。
如果您的对象之间有更多重复的逻辑,您可以将它们合并到一个策略对象中,这两个对象都有一个实例(而不是从中继承)。本质上,这将是您的代表的代表(这很好)。或者,如果您有一组相关的共享函数,您可以使它们成为某些策略 class 的 class 方法。但是如果只是像这样一个单一的方法,一个函数就好了。
我只包含了下面的相关代码片段,供您了解如何使用单独的 class 来为您实现此目标。
@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
我有一个 ViewController class 和一个视图 class。 ViewController 有一个 UIScrollView,View 有一个 UITableView,两者都是 UIScrollViewDelegate 的委托。
View 和 ViewController 都使用了 scrollViewDidScroll:
委托方法,并且都具有相同的代码。这显然是重复的,所以我想解决这个问题。
问题是我不知道怎么做。
我无法将功能提取到基础 class 中,我也不认为我可以有一个单独的 class 实现该方法,然后我可以使用它的实例(这是可能的在 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));
}
}
}
创建一个函数来封装你想要的东西,并将任何需要的变量(可能包括self
)传递给它。
如果您的对象之间有更多重复的逻辑,您可以将它们合并到一个策略对象中,这两个对象都有一个实例(而不是从中继承)。本质上,这将是您的代表的代表(这很好)。或者,如果您有一组相关的共享函数,您可以使它们成为某些策略 class 的 class 方法。但是如果只是像这样一个单一的方法,一个函数就好了。
我只包含了下面的相关代码片段,供您了解如何使用单独的 class 来为您实现此目标。
@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