作为一个不是训练有素的程序员的人,我现在已经在脑后留下了一个挥之不去的问题。假设我想向用户呈现5个单独的“集合”或信息视图,但每个ViewController需要一些自定义,例如更改标签,甚至位置和某些UIElements的类型..
一个例子是提供不同类型数据的统计数据(例如身高,体重,心率等)。所有视图都有标题,但它们不同,它们有图表,但有不同的基础类型(Int vs Double)和一些观点会比其他观点提供更多的统计数据。
你是“有效”意味着什么的判断,例如速度或便利性或未来的进一步定制,或其他。
更好的是,是为每个视图创建一个UIViewController子类,复制一些代码,还是用IFTTT,数组等逻辑创建一个VC,这样你就可以重用部分代码了?
答案 0 :(得分:1)
我喜欢创建所有其他视图控制器继承的父视图控制器(让它称之为RootViewController)。这样,如果我需要做一些会影响他们的事情,我可以把它放在一个地方。
例如:
(RootViewController.h)
@interface RootViewController : UIViewController {
UIActivityIndicatorView *spinner;
UIView *spinnerBkgd;
}
- (void) setSpinnerMessage:(NSString *)message;
- (void) showSpinner;
- (void) hideSpinner;
@end
(RootViewController.m)
#import "RootViewController.h"
@interface RootViewController () {
BOOL spinnerAnimating;
UILabel *spinnerLabel;
}
@end
@implementation RootViewController
- (void) viewDidLoad {
[super viewDidLoad];
float longestDimension = self.view.frame.size.width;
if (self.view.frame.size.width < self.view.frame.size.height)
longestDimension = self.view.frame.size.height;
UIView *spinnerParentView = self.navigationController.view;
if (!spinnerParentView)
spinnerParentView = self.view;
spinnerBkgd = [[UIView alloc] initWithFrame:(CGRect){ 0, 0, longestDimension, longestDimension }];
spinnerBkgd.backgroundColor = [UIColor blackColor];
spinnerBkgd.alpha = 0.0f;
[spinnerParentView addSubview:spinnerBkgd];
spinnerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 400, 60)];
spinnerLabel.textColor = [UIColor whiteColor];
spinnerLabel.font = [UIFont systemFontOfSize:18.0f];
spinnerLabel.textAlignment = NSTextAlignmentCenter;
[spinnerBkgd addSubview:spinnerLabel];
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.frame = CGRectMake(0, 0, 100, 100);
spinner.center = self.view.center;
[spinnerBkgd addSubview:spinner];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showSpinner)
name:JBB_SHOW_SPINNER
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateStatusMessage:)
name:JBB_UPDATE_STATUS_MESSAGE
object:nil];
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
spinnerAnimating = NO;
[self resetInternalFrames];
}
- (void) setSpinnerMessage:(NSString *)message {
spinnerLabel.text = message;
}
- (void) showSpinner {
dispatch_async(dispatch_get_main_queue(), ^{
if (!spinnerAnimating) {
spinnerLabel.text = @"";
[UIView animateWithDuration:0.8f
delay:0.2f
options: UIViewAnimationOptionAllowAnimatedContent
animations:^{
spinnerBkgd.alpha = 0.6f;
}
completion:^(BOOL finished){
//NSLog(@"show spinner");
}];
[spinner startAnimating];
spinnerAnimating = YES;
}
});
}
- (void) hideSpinner {
dispatch_async(dispatch_get_main_queue(), ^{
//NSLog(@"hide spinner");
spinnerBkgd.alpha = 0.0f;
[spinner stopAnimating];
spinnerLabel.text = @"";
spinnerAnimating = NO;
});
}
- (void) updateStatusMessage:(NSNotification*)notification {
dispatch_async(dispatch_get_main_queue(), ^{
[self setSpinnerMessage:[notification.userInfo objectForKey:@"statusMessage"]];
});
}
- (void) resetInternalFrames {
spinner.center = self.view.center;
spinnerLabel.center = (CGPoint) { self.view.center.x, self.view.center.y - 90 };
}
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self resetInternalFrames];
}
@end
通过上面的示例,任何子类RootViewController的视图控制器都可以利用我的全屏微调器(加载内容时)。
我也开始制作&#34; Base Cells&#34;对于集合视图,其他&#34; Cells&#34;子类。通常,有一些共同的功能可以放入一个由所有东西共享的基类中。任何需要条件的东西(if(x支持)然后显示y)都需要进入特定的子类。但是,如果它是2个或更多子类中的东西,我将子类化为root,并生成其他2个子类。
粗略的例子,有名称:
RootCollectionViewCell:UICollectionViewCell
+-- RootScrollviewCollectionViewCell:RootCollectionViewCell
+-- FriendCell:RootScrollviewCollectionViewCell
+-- MediaCell:RootScrollviewCollectionViewCell
+-- PhotosCell:MediaCell
+-- VideosCell:MediaCell
+-- DetailCell:RootCollectionViewCell
+-- FeelingsCell:RootCollectionViewCell
这样,照片和视频单元就是mediacell的子类,mediacell是我的scrollview单元的子类。其余的只显示内容而没有滚动视图,因此从根目录继承。
答案 1 :(得分:0)
如果你的viewConrollers有一些常见的'逻辑代码',即创建一些统计信息或设置一些信息,那应该驻留在一个parentViewController中,并且所有信息都应该继承该父代。
UI自定义当然应该在单独继承的UIViewControllers中完成。
你几乎不应该编写一个ViewController类,它有一大部分if / else语句设置自己的UI。
执行前者将使代码更清晰,并提供更多可维护性。
到目前为止,我见过的几乎所有代码都是人们使用这种特殊的方法。一些例外,其中2个视图非常紧密地链接,而简单的if / else将解决它们之间的差异。