自定义ViewController适用于除一个以外的所有子视图。为什么是这样?

时间:2012-08-31 18:15:24

标签: ios inheritance uiviewcontroller utility

虽然我无法发布确切代码(NDA),但我可以花点时间来解释它的设计和实现方式。

首先,我目前正在做的就是通过生成静态页面和编写要触发的事件来实现前端。

我写的很多页面都有非常相似的属性。其中包括:

  • 相同的背景效果和图像。
  • 带有背景的导航栏,以及导航栏的标题,提醒用户他们当前所在的页面。
  • 用于自定义目的的其他视图。

因此,我决定编写自己的自定义ViewController,我觉得我写的页面可以继承。对于我写的前两个页面,一切都按计划工作:我所要做的只是继承类,指定我的设置,而父ViewController将在渲染所需模板方面处理其他所有事情;后退按钮会准确显示它应该在的位置,当我按下它时,它会从ViewController堆栈中弹出,然后返回到主页。

它的工作原理如下:

  • 父类包含NSMutableDictionary*(称为_additionalViews,即@protected),并在页面创建开始时通过[super initWithNibName]进行初始化 - 其中包含重载父类的附加withNavTitle:(NSString*)navTitle参数以及它的每个子类。
  • 子类只是在初始化时通过将相关键添加到_additionalViews来指定要创建的视图。调用viewDidLoad方法后,通过按键遍历_additionalViews并调用[self.view addSubview:[_additionalViews objectForKey:key]]
  • 来加载所有内容
  • 当按下后退按钮时,对象从viewController堆栈弹出的事件由类而不是子类进行管理和触发。

我确信你可以看到,这个想法减少了很多代码膨胀并使事情可以重复使用。我用这种方法编写的前两页基本上是静态信息页面,后退按钮与它们完美配合(以及指向网页的链接和我向它们投掷的各种其他事件)。

但是,现在,当我创建这个新页面时,所有内容都呈现,但没有任何功能。我正在以与前两页相同的方式做所有事情。这是为什么 - 这怎么可能?

我能做的是提供一些我为按钮和链接等编写的实用功能。如果有人在这些中看到任何这可能不是一个好主意,我会非常感谢您的反馈。他们肯定会渲染,并为前两页工作。不是最后一个。

我很感激帮助(我现在只用Objective-C写了1.5个月了,所以我还是相当新的 - 但我确实有一个不错的C ++背景。)

代码 - 标题和来源合并

#import <UIKit/UIKit.h>

typedef struct __TextAttributes__ {
    UIColor* textColor;
    bool isBold;
    CGFloat fontSize;
    NSString* text;

} TextAttributes;

typedef struct __ButtonAttributes__ {

    UIControlState  controlState;
    UIControlEvents controlEvents;
    NSString*       imgPath;
    id              target;
    SEL             selector;
} ButtonAttributes;

UITextView* UITextView_Make_NoEdit(NSString* displayText, CGFloat fontSize, bool useBoldFont, CGRect frameDims, UIColor* color, id delegate);

UIButton* Link_Make(NSString* linkText, CGFloat fontSize, bool useBoldFont, 
                    SEL actionSelector, id target, CGRect frameDims);

UIButton* Button_Make_Custom(TextAttributes* ta, ButtonAttributes* attr, CGRect frameDims, bool freeBtnAttr, bool freeTextAttr);

ButtonAttributes* ButtonAttributes_Make(NSString*imgName, NSString* imgType, UIControlState controlState, UIControlEvents controlEvents, id target, SEL selector);

void ButtonAttributes_Free(ButtonAttributes* attr);

TextAttributes* TextAttributes_Make(NSString* text, UIColor* textColor, CGFloat fontSize, bool isBold);

void TextAttributes_Free(TextAttributes* attr);

//-------------------
// Global Functions  
//-------------------

//----------------------------------------
static const float TextFont_Alpha = 0.75;
//----------------------------------------

typedef enum __MemoryType__ {
    MemoryTypeTextAttributes,
    MemoryTypeButtonAttributes
} MemoryType;

static void CheckMemAndThrow(void* mem, MemoryType mt )
{
    if (mem)
        return;

    NSString *memTypeAndFunc, *msg;

    switch (mt) {
        case MemoryTypeButtonAttributes:
            memTypeAndFunc = @"ButtonAttributes in ButtonAttributes_Make(...)";
            break;
        case MemoryTypeTextAttributes:
            memTypeAndFunc = @"TextAttributes in TextAttributes_Make(...)";
            break;
    }

    msg = [NSString stringWithFormat:@"Memory allocation error for %@", [memTypeAndFunc autorelease]];

    @throw [[NSException alloc] initWithName:@"MemoryAllocException" reason:msg userInfo:nil];
}

UITextView* UITextView_Make_NoEdit(NSString* displayText, CGFloat fontSize, bool useBoldFont, CGRect frameDims, UIColor* color, id delegate) 
{
    UITextView* view = [[UITextView alloc] initWithFrame:frameDims];

    [view setText:displayText];

    UIFont* font;

    if (useBoldFont)
    {
        font = [UIFont boldSystemFontOfSize:fontSize];
    }
    else 
    {
        font = [UIFont systemFontOfSize:fontSize];
    }

    [view setTextColor:color];
    [view setDelegate:delegate];
    [view setEditable:NO];
    [view setScrollEnabled:NO];
    [view setBackgroundColor:[UIColor clearColor]];
    [view setFont:font];
    [font release]; 

    return view;
}

static const CGFloat Default_Link_Red   = 1.0f / 255.0f;
static const CGFloat Default_Link_Green = 184.0f / 255.0f;
static const CGFloat Default_Link_Blue  = 252.0f / 255.0f;
static const CGFloat Default_Link_Alpha = 1.0f;

UIButton* Link_Make(NSString* linkText, 
                    CGFloat fontSize, 
                    bool useBoldFont, 
                    SEL actionSelector, id target, 
                    CGRect frameDims) 
{
    UIButton* linkButton = [UIButton buttonWithType:UIButtonTypeCustom]; 


    [linkButton setFrame:frameDims];

    [linkButton setTitleColor:[UIColor colorWithRed:Default_Link_Red 
                                              green:Default_Link_Green 
                                               blue:Default_Link_Blue 
                                              alpha:Default_Link_Alpha] 

                     forState:UIControlStateNormal];

    [linkButton setTitle:linkText forState:UIControlStateNormal];

    UIFont* font;

    if (useBoldFont) 
    {
        font = [UIFont boldSystemFontOfSize:fontSize];
    } 
    else 
    {
        font = [UIFont systemFontOfSize:fontSize];
    }

    [linkButton.titleLabel setFont:[font retain]];

    [linkButton addTarget:target action:actionSelector forControlEvents:UIControlEventTouchDown];

    [font release];

    return linkButton;
}

UIButton* Button_Make_Custom(TextAttributes* attr, ButtonAttributes* buttonAttr, CGRect frameDims, bool freeBtnAttr, bool freeTextAttr)
{

    UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];

    [btn setTitle:attr->text forState:buttonAttr->controlState];
    [btn setTitleColor:attr->textColor forState:buttonAttr->controlState];
    [btn setBackgroundColor:[UIColor clearColor]];

     if (attr->isBold) 
     {
         [btn.titleLabel setFont:[UIFont boldSystemFontOfSize:attr->fontSize]];
     } 
     else 
     {
         [btn.titleLabel setFont:[UIFont systemFontOfSize:attr->fontSize]];
     }

    [btn setFrame:frameDims];

    [btn setBackgroundImage:[UIImage imageWithContentsOfFile:[buttonAttr->imgPath retain]] forState:buttonAttr->controlState];

    [btn addTarget:buttonAttr->target 
            action:buttonAttr->selector 
  forControlEvents:buttonAttr->controlEvents];

    if (freeTextAttr)
        TextAttributes_Free(attr);

    if (freeBtnAttr)
        ButtonAttributes_Free(buttonAttr);

    if (![btn isEnabled])
        [btn setEnabled:YES];

    return btn;
}

ButtonAttributes* ButtonAttributes_Make(NSString* imgName, NSString* imgType, UIControlState controlState, UIControlEvents controlEvents, id target, SEL selector) 
{
    ButtonAttributes* btnAttr = (ButtonAttributes *)calloc(1, sizeof(ButtonAttributes));

    CheckMemAndThrow((void*)btnAttr, MemoryTypeButtonAttributes);

    btnAttr->imgPath       = [[NSBundle mainBundle] pathForResource:imgName ofType:imgType];
    btnAttr->controlState  = controlState; 
    btnAttr->controlEvents = controlEvents;
    btnAttr->target        = target;
    btnAttr->selector      = selector;

    return btnAttr;
}

void ButtonAttributes_Free(ButtonAttributes* attr)
{
    if (!attr)
        return; 

    if (attr->imgPath)
        [attr->imgPath release];

    free(attr);
}

TextAttributes* TextAttributes_Make(NSString* text, UIColor* textColor, CGFloat fontSize, bool isBold)
{
    TextAttributes* textAttributes = (TextAttributes *)calloc(1, sizeof(TextAttributes));

    CheckMemAndThrow((void*)textAttributes, MemoryTypeTextAttributes);

    textAttributes->text      = text;
    textAttributes->textColor = textColor;
    textAttributes->fontSize  = fontSize;
    textAttributes->isBold    = isBold;

    return textAttributes;
}

void TextAttributes_Free(TextAttributes* attr)
{
    if (!attr)
        return;

    if (attr->text) {
        [attr->text release];
    }

    if (attr->textColor) {
        [attr->textColor release];
    }

    free(attr);
}

0 个答案:

没有答案