IOS 开发学习(3): IOS UI架构设计

来源:互联网 发布:mac chrome广告终结者 编辑:程序博客网 时间:2024/05/22 01:48

分类: 软件技术【IOS 】 软件架构 8573人阅读 评论(7) 收藏 举报

IOS 严格秉承MVC模式, 即每个View的出现将有相应的Controller负责其逻辑事物, 因此IOS的UI设计中需要首先考虑MVC的问题. 在本博客中,在兼顾MVC的同时,考虑了两点设计中常用的问题。 

1. IOS中对可重用UI的处理(能重用的UI通过Controller特别封装, 提供给其它View进行重用) 

   UI涉及的一个非常重要的问题,跟程序设计也是一样, 如何管理冗余(即重复信息)的信息, 冗余度的处理实际上不单单是程序设计的死敌,同样是管理的死敌(冗余代码是Bug的温床,同样如此,雷同UI是用户体验的死敌)。

    对付重复性,我们这里一个小需求是, 如何实现一个类似于ListView的功能, 让所有的UI的小Item都能不断的加入到父面板中? UI如下:

   

图:不断增加一个重复的UI

当然,也许有人说用UITableView可以做到, 但是更个性化的Item, 会很需要一个类似的结构来达成我们的目的。并且,你一定会面临这样的问题,相同的数据结构,需要用同一个UI展示。当你辛苦的设计好一个UI以及逻辑之后,发现在另外相似的情况下复用,已经痛不欲生,因此, 这里我们采用的一种方式是: 封装好一个小的UI. 然后随处可用。

a. 隔离


图: 父面板实际上可以是任意的


图:在任意需要的地方,调用这个小东西

b. 代码中加载

[cpp] view plaincopy
  1. //  
  2. //  KEYI_ViewController.m  
  3. //  LoadPartView  
  4. //  
  5. //  Created by 尘 凡 on 12-12-28.  
  6. //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #import "KEYI_ViewController.h"  
  10.   
  11. @interface KEYI_ViewController ()  
  12.   
  13. @end  
  14.   
  15. @implementation KEYI_ViewController  
  16.   
  17. - (void)viewDidLoad  
  18. {  
  19.     [super viewDidLoad];  
  20.     //仅仅只是为了获取view的大小, 这个controller设置为autoRelease  
  21.     LiteController *tempControl = [[[LiteController alloc] initWithNibName:@"LiteController" bundle:nil] autorelease];  
  22.     UIView *liteView = tempControl.view;  
  23.     CGPoint point = liteView.center;  
  24.       
  25.     CGSize  size = liteView.bounds.size;  
  26.     //不知道为什么, 需要代码初始化这个ScrollView, IB拖拉的方式构造界面,会无效  
  27.     UIScrollView *parentView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];  
  28.     [self.view addSubview:parentView];  
  29.       
  30.     int len = 75;  
  31.     for (int i = 0; i < len; i++) {  
  32.         CGFloat centX = point.x;  
  33.         CGFloat centY = point.y + i * size.height;  
  34.         NSString *string = [NSString stringWithFormat:@"%d",i];   
  35.         [self addItems:centX :centY:parentView:string];  
  36.     }  
  37.     parentView.contentSize = CGSizeMake(320, len* size.height);  
  38.     parentView.scrollEnabled = YES;  
  39. }  
  40.   
  41. - (void) addItems:(CGFloat)centX:(CGFloat)centY:(UIScrollView *)parentView:(NSString*)title  
  42. {  
  43.     LiteController *contr = [[LiteController alloc] initWithNibName:@"LiteController" bundle:nil];  
  44.     UIView *aItem = contr.view;  
  45.     [contr.textLabel setText:title];  
  46.     aItem.center = CGPointMake(centX, centY);  
  47.     aItem.backgroundColor = [UIColor grayColor];  
  48.     [parentView addSubview:aItem];  
  49.       
  50. }  
  51.   
  52. - (void)viewDidUnload  
  53. {  
  54.     [super viewDidUnload];  
  55.     // Release any retained subviews of the main view.  
  56. }  
  57.   
  58. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  59. {  
  60.     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);  
  61. }  
  62.   
  63. - (void)dealloc {  
  64.     [super dealloc];  
  65. }  
  66. @end  


上述部分的源码提供下载

2. IOS中对个性化页面的处理: 个性化中,公用UI进行提炼, 个性化的UI自己负责自己的Controller以及XIB文件

    下图是一个典型的个性化页面处理情况,点击4个Tab按钮将出现不同的UI.

      

  

   

面对这样的个性化特征很强的界面, 按照程序设计的低耦合原则, 应该将可变化的部分, 安插在影响最小的位置,比如【注册】的UI/逻辑不能影响【登陆】的UI以及逻辑, 这里,我是按照这样的方式:

a. 公共部分, 如上层按钮, 放在一个controller中. 见下图:


图: 一个全局的Controller, 相当PC中CPU的作用: 组装

 

b. 各个按钮对应的不同界面,各自建立Controller. 见下图:


图: 【登陆】已经被封装到自己的Controller, 最小耦合度原则



图: 【注册】已经被封装到自己的Controller, 最小耦合度原则

c. 关键的代码, 加载各自不同的Controller

头文件

[cpp] view plaincopy
  1. //  
  2. //  ControllerUsrMgr.h  
  3. //  keyiApp  
  4. //  
  5. //  Created by 尘 凡 on 12-12-14.  
  6. //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10. #import "ControllerMod.h"  
  11. #import "ControllerLogin.h"  
  12. #import "ControllerRegister.h"  
  13. #import "ControllerForget.h"  
  14. #import "ToolUI.h"  
  15.   
  16. @interface ControllerUsrMgr : UIViewController  
  17. {  
  18.       
  19.     IBOutlet UILabel *selTitle;  
  20.     IBOutlet UIButton *changeBtn;  
  21.     IBOutlet UIButton *forgotBtn;  
  22.     IBOutlet UIButton *regBtn;  
  23.     IBOutlet UIButton *loginBtn;  
  24.     IBOutlet UIView *parentView;  
  25.     IBOutlet UILabel *titleInfo;  
  26.     NSArray *btnArr;  
  27.     NSArray *selImgArr;  
  28.     NSArray *unSelImgArr;  
  29.     NSArray *upperTitle;  
  30.     NSArray *lowerTitle;  
  31.     ControllerLogin *loginCtr;  
  32.     ControllerRegister *registerCtrl;  
  33.   
  34.       
  35. }  
  36. - (IBAction)actionLogin:(UIButton *)sender;  
  37. - (IBAction)actionRegister:(UIButton *)sender;  
  38. - (IBAction)actionForgot:(UIButton *)sender;  
  39. - (IBAction)actionChange:(UIButton *)sender;  
  40.   
  41. @end  

源文件

[cpp] view plaincopy
  1. //  
  2. //  ControllerUsrMgr.m  
  3. //  keyiApp  
  4. //  
  5. //  Created by 尘 凡 on 12-12-14.  
  6. //  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.  
  7. //  
  8.   
  9. #import "ControllerUsrMgr.h"  
  10.   
  11. @interface ControllerUsrMgr ()  
  12.   
  13. @end  
  14.   
  15. @implementation ControllerUsrMgr  
  16.   
  17. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  18. {  
  19.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  20.     if (self) {  
  21.         // Custom initialization  
  22.         unSelImgArr = [[NSArray alloc] initWithObjects:@"usr_mgr_login_nosel.png",@"usr_mgr_reg_nosel.png",@"usr_mgr_mod_nosel.png",@"usr_mgr_login_nosel.png", nil];  
  23.         selImgArr = [[NSArray alloc] initWithObjects:@"usr_mgr_login_sel.png",@"usr_mgr_reg_sel.png",@"usr_mgr_mod_sel.png",@"usr_mgr_login_sel.png", nil];  
  24.         lowerTitle = [[NSArray alloc] initWithObjects:@"请填写登陆信息",@"请填写注册信息",@"请填写申诉信息",@"请填写修改信息", nil];  
  25.         upperTitle = [[NSArray alloc] initWithObjects:@"用户登陆",@"用户注册",@"忘记密码",@"修改密码", nil];  
  26.         loginCtr = [[ControllerLogin alloc]initWithNibName:@"ControllerLogin" bundle:nil];  
  27.         registerCtrl = [[ControllerRegister alloc]initWithNibName:@"ControllerRegister" bundle:nil];  
  28.           
  29.     }  
  30.     return self;  
  31. }  
  32.   
  33. - (void)viewDidLoad  
  34. {  
  35.     [super viewDidLoad];  
  36.     btnArr = [[NSArray alloc] initWithObjects:loginBtn,regBtn,changeBtn,forgotBtn, nil] ;  
  37.       
  38.     [self actionLogin:loginBtn];  
  39. }  
  40.   
  41. - (void)viewDidUnload  
  42. {  
  43.     [loginBtn release];  
  44.     loginBtn = nil;  
  45.     [regBtn release];  
  46.     regBtn = nil;  
  47.     [forgotBtn release];  
  48.     forgotBtn = nil;  
  49.     [changeBtn release];  
  50.     changeBtn = nil;  
  51.     [parentView release];  
  52.     parentView = nil;  
  53.     [titleInfo release];  
  54.     titleInfo = nil;  
  55.     [selTitle release];  
  56.     selTitle = nil;  
  57.     [super viewDidUnload];  
  58.     // Release any retained subviews of the main view.  
  59.     // e.g. self.myOutlet = nil;  
  60. }  
  61.   
  62. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  63. {  
  64.     return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  65. }  
  66.   
  67. - (void)dealloc {  
  68.     [loginBtn release];  
  69.     [regBtn release];  
  70.     [forgotBtn release];  
  71.     [changeBtn release];  
  72.     [parentView release];  
  73.     [titleInfo release];  
  74.     [selTitle release];  
  75.     [super dealloc];  
  76. }  
  77.   
  78. - (IBAction)actionLogin:(UIButton *)sender {  
  79.     [ToolUI removeSubView:parentView];  
  80.     [parentView addSubview:loginCtr.view];  
  81.     [self highLightButton:sender];      
  82. }  
  83.   
  84.   
  85.   
  86. - (IBAction)actionRegister:(UIButton *)sender {  
  87.     [ToolUI removeSubView:parentView];  
  88.     [parentView addSubview:registerCtrl.view];  
  89.     [self highLightButton:sender];  
  90.   
  91. }  
  92.   
  93. - (IBAction)actionForgot:(UIButton *)sender {  
  94.          [ToolUI removeSubView:parentView];  
  95.          [self highLightButton:sender];  
  96. }  
  97.   
  98. - (void) pressOne:(UIButton *)curBtn {  
  99.     if (curBtn == loginBtn)  
  100.     {  
  101.         [curBtn performSelector:@selector(highLightButton:) withObject:curBtn afterDelay:0.1];  
  102.     }  
  103. }  
  104.   
  105. - (void) highLightButton:(UIButton *)b{  
  106.       
  107.     for (int i = 0; i < btnArr.count; i++) {  
  108.         UIButton *item = [btnArr objectAtIndex:i];  
  109.         NSString *unSel = [unSelImgArr objectAtIndex:i];  
  110.         NSString *sel = [selImgArr objectAtIndex:i];  
  111.         if (b == item) {  
  112.             [item setBackgroundImage:[UIImage imageNamed:sel] forState:UIControlStateNormal];  
  113.             [selTitle setText:[upperTitle objectAtIndex:i]];  
  114.             [titleInfo setText:[lowerTitle objectAtIndex:i]];  
  115.         }  
  116.         else {  
  117.             [item setBackgroundImage:[UIImage imageNamed:unSel] forState:UIControlStateNormal];  
  118.         }  
  119.     }  
  120. }  
  121.   
  122. - (IBAction)actionChange:(UIButton *)sender {  
  123.           
  124.         [ToolUI removeSubView:parentView];  
  125.         [self highLightButton:sender];  
  126.         
  127. }  
  128. @end  


附注:

参考 1: 苹果教程: UIViewControler知识

参考2:  中枪:  XCode ios iphone 变态的资源管理   非常混乱的说....

参考3:  中枪, 删除默认的view之后产生的新问题

0 0