虽然我不能发布确切的代码 (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);
}