ios - 什么是最有效的 : Customized or adapted ViewControllers?

标签 ios

作为一个不是受过训练的程序员的人,几个月来我一直有一个挥之不去的问题。假设我想向用户呈现 5 个单独的“集合”或信息 View ,但每个 ViewController 都需要进行一些自定义,例如更改标签、甚至位置和某些 UIElement 的类型。

一个例子是显示不同类型数据的统计数据(例如高度、体重、心率等)。所有的 View 都有标题,但它们是不同的,它们有图表,但具有不同的底层类型(Int 与Double),一些 View 会比其他 View 显示更多的统计信息。

您可以判断“高效”的含义,例如速度或便利性或 future 的进一步定制,或其他。

更好的是,为每个 View 创建一个 UIViewController 子类,并复制一些代码,或者创建一个具有 IFTTT、数组等逻辑的 VC,以便您可以重用部分代码?

最佳答案

我喜欢创建一个所有其他 View Controller 都继承的父 View Controller (我们称之为 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 的 View Controller 都可以利用我的全屏微调器(在加载内容时)。

我也开始为 Collection View 制作“Base Cells”,这是其他“Cells”的子类。通常,可以将通用功能放入一个由所有对象共享的基类中。任何需要条件(如果(支持 x)则显示 y)的东西都需要进入特定的子类。但是,如果它会在 2 个或更多子类中,我将对根进行子类化,并创建其他 2 个子类。

粗略的例子,虚构的名字:

RootCollectionViewCell:UICollectionViewCell
+-- RootScrollviewCollectionViewCell:RootCollectionViewCell
   +-- FriendCell:RootScrollviewCollectionViewCell
   +-- MediaCell:RootScrollviewCollectionViewCell
       +-- PhotosCell:MediaCell
       +-- VideosCell:MediaCell
+-- DetailCell:RootCollectionViewCell
+-- FeelingsCell:RootCollectionViewCell

这样,照片和视频单元格成为 mediacell 的子类,mediacell 又成为我的 ScrollView 单元格的子类。其余的只是显示没有 ScrollView 的内容,所以从根继承。

关于ios - 什么是最有效的 : Customized or adapted ViewControllers?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28884073/

相关文章:

ios - 为什么我们需要将 View 的引用导出设置为文件的所有者

ios - 范围无效 :basic_info. 请改用 public_profile、user_friends

ios - iTunes Connect:带有特殊字符的公司名称

ios - 第三方应用程序可以访问其他应用程序的通知吗?

ios - Xcode 8's simulator won' t 工作

ios - 指定初始化程序?

ios - Force iOS 应用程序在 safari 中打开外部链接

objective-c - 如何制作 UITextView Wrap 以容纳其中的文本?

ios - SwiftUI - 当放置在 macOS 上的列表中时,文本字段被禁用(不可编辑)

ios - FMDB 和索引 0 超出空数组的范围