1:程序第一次进入的时候,通过判断沙盒(偏好设置中)中保存的版本号和程序运行的版本号进行判断。如果不相同,就进入新特性页面 ——》
》1:新特性页面展示的新特性图片,都是从plist中读取出来,最终读取出来的plist的图片信息,放在scrollerview上展示
》2: 在新特性页面,中最后一个uIImageview,放入一个开始按钮。(注意,把图片背景拉伸的方法,按钮背景
2:在展示主界面的viewDidLoad方法中此时从沙盒(document)中读取有没有access_token(即调用单例方法) 判断是否是第一次登陆,如果没有登陆立即弹出登陆模态对话框
》2_1:登陆模态对话框,中view是webview,通过新浪的连接,加载新浪的登陆界面。在webview 中代理方法shouldStartLoadWithRequest 监听新浪返回的access token ,如果返回access_token立即写入沙盒。一般写入沙盒,都自定义实体,用归档。其中自定义一个微博帐号实体,实现nsCoding ,被写入沙盒。
>2:其中新浪微博帐号实体(access_token ,uid,screen_name,experinTime)
要写成单例类,因为每次向新浪微博发送请求,都要用access_token ,uid等字段,所以最好写入单例,供整个程序使用
单例类:重写 alloc init retain retaincount, release ,copy,等方法 用一个静态变量进行判读,如果是第一次,就创建,不是的直接返回,单利是一致存在。其中单利类的对象字段都不用释放,最好是简单字段。
在单利类中定义一个静态方法,方法调用 :也是通过一个静态变量进行判断,如果存在直接返回,如果存在,先从沙盒中去,如果沙盒中没有,就直接创建。
》3:授权成功之后,直接跳到 主界面,
3:主界面 是一个自定义tabbarControllerview.
1: 主界面是一大的控制器 ——》主的控制区(大的)有2个部分组成 一个contentview 和下面 tabbarview组成。 其中下面的tabbarview 中导航按钮有 这个主控制里面装有的子导航控制器决定。
、 2:初始化大控制器中contentview,确定位置 。
3:;初始化5个导航控制器(5个导航控制器中有各自的根控制器和导航控制器的描述(其中导航器对应描述是一个实体)在主控制中 持有5个子控制器和5个导航控制描述)。其中导航控制是系统即可,并且设置导航控制中子控制的默认的导航title。
代码如下。
-(void)InitController{
HomeController *home = [[HomeController alloc] init];
[self addController:home title:@"首页" normal:@"tabbar_home.png" highlighted:@"tabbar_home_highlighted.png"];
[home release];
MyDataController *data = [[MyDataController alloc] init];
[self addController:data title:@"我的资料" normal:@"tabbar_message_center.png" highlighted:@"tabbar_message_center_highlighted.png"];
[data release];
FriendController *friend = [[FriendController alloc] init];
[self addController:friend title:@"我的关注" normal:@"tabbar_profile.png" highlighted:@"tabbar_profile_highlighted.png"];
[friend release];
FollowerController *follower = [[FollowerController alloc] init];
[self addController:follower title:@"我的粉丝" normal:@"tabbar_discover.png" highlighted:@"tabbar_discover_highlighted.png"];
[follower release];
UIViewController *more = [[UIViewController alloc] init];
more.view.backgroundColor = [UIColor darkGrayColor];
[self addController:more title:@"更多" normal:@"tabbar_more.png" highlighted:@"tabbar_more_highlighted.png"];
[more release];
}
》===================================》
-(void)addController:(UIViewController *)viewcontroller title:(NSString *)title normal:(NSString *)normal highlighted:(NSString *)hightlight{
//包装成导航控制器
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:viewcontroller];
viewcontroller.navigationItem.title=title;
nav.delegate=self;
TabbarItemDesc *desc=[TabbarItemDesc TabbarItemTitle:title normal:normal height:hightlight];
[_viewcontrollerdatas addObject:desc];
[self addChildViewController:nav];
[nav release];
4: 初始化tabbar的位置和创建下面的导航按钮
4.1即在主控制器中指定tabbar的位置,因为tabbar是自定义view的。把主控制器中持有5个导航控制描述集合,传入进去——》然后在内部,根据传入导航控制器描述的集合,创建5个按钮,并且设置按钮的描述信息和背景图片 。
4.2 要把排号导航信息和导航的图片要重写button按钮,并且传入 描述信息,图片。之后重写button的两个方法重新调整。
一个label 方法-(CGRect)titleRectForContentRect:(CGRect)contentRect{
一个是imageview方法
-(CGRect)imageRectForContentRect:(CGRect)contentRect{
4.3 在tabbar 中创建多个button,之后,分别附上 tag属性 最好是按顺序的——》并且注册button的点击按钮-管理 按钮的点击事件。
——》设置按钮点击选中背景的切换,和变在外面 控制对应的导航控制器
——》记录上一个点击按钮的和当前点击按钮的信息,进行内部切换背景(移出上一个,的状态,更新当前的状态。
——》要外部控制 各自导航控制器官 ,要传出去,需要自定义协议(代理)和主控制器进行交互。
à然后主控制实现tabbar定义的代理方法,监听 tabbar中按钮的事件(传出当前按钮的tag 和上一个按钮的tag),通过传出的两个tag,然后在主控制器集合中取出来控制器的view 在contentview,中remove(取出上一个控制器,然后remove当控制器的view 和add(取出当前控制器view出去来添加到contentview中)
。
第二步:主控制中添加了5个子导航控制器,然后在添加导航控制器中,设置代理
在代理方法中(navigationController willShowViewController)监听每个导航控制器中即将出来的viewcontroller. 进行判断 1-2之间中可以加动画实现。
可以用uiview 实现动画——》
1:如果是根控制器——》 显示tabbar(就是把tabbar的y坐标=self.view的高度-tabbar的高度。Contentview的(height)高度=self.view的高度-)tabbar的高度
2:如果不是根控制器——》把tabbar的高度(就tabbar的y的坐标=self.view的高度。 Contentview 的高度=self.view的高度。
说明图层动画——》就是针对于图层上变化 转场动画和uiview动画。
3:然后在不是根控制器中,即将显示viewcontroller可以可以设置 定制left的导航(用button)和右边的导航控制器,button的按钮用image的大小。
并且注册监听事件。进行pop根控制器和栈顶控制器。 这样统一监听和同一个管理
我的关注和我的粉丝:两个模块 ——》新浪微博服务器返回 用户信息(user)和最近条微博(statu)的数据模型是一样的,只是 请求的连接不同。
只要是返回数据的模型一样,就可以抽取一个父类,然后在父类 公布一个方法,让子类各自实现。统一由父类调用。实现不同的数据。
我的粉丝和我的关注的分析
1: 实体: 用户类 (user) status (微博类)此时一对一。(其中user中持有user类)
2:在dao:使用ASIHttpRequest 框架 向服务器发送请求,然后代理把结果返回,(注意请求是异步线程,返回结果回到主线程)注意 ASIHttpRequest 是异步线程请求,返回到主线程的时候,在外面viewcontroller中调用对象可能早就释放了。
所以内部要持有这个对象,知道请求完成,调用完成对象block,之后就可以销毁。
在调用 的时候self retain ——》在代理调用完成之后block self release
或者在失败的时候 self release;
1:提供一个方法 是根据不同url和uid等信息, 向服务器发送请求(方法内部封装,ASIHttpRequest 向新浪微博服务器发送请求)。
然后在代理,来监听返回的数据,用sbjson来进行新浪返回的数据。返回的数据,一般用block返回出去,方面在外面调用的控制器号接受数据
block的参数1:返回成功的数据 2:返回错误的信息,3:分页数,总页数)
2:分别提供两个方法 :分别是 粉丝和关注的方法 方标外部调用,实现动态 发送请求。两个方法内部调用(1:内部的方法,即返回外面的数据相同)
3:自定基类——》里面实现uitableview 在viewload里面 调用上面的dao的请求的信息。在调用发送向新浪微博请求的信息的方法 ,
》3.1 此时把这个方法 父类 提取一个公用方法,父类不现实让子类去实现各自逻辑。然后判断如果子类实现这个方法,父类在回调回来。就可以接受数据了。每个子类只要实现父类的方法,就即可,接受数据(因为数据相同,如果不相同不能公用),由父类完成。然后重现加载数据(reload )
》3.2 在tabviewcell ,进行赋值,注意的是给cell中图片赋值的时候——》
此时图片要实现异步下载。
此时异步下载,是自己实现一个任务,把任务放在一个队列执行异步下载。
自定义任务 继承NSOperation 重写main方法 :main方法的实现说明
1:main里面的方法 放在队列中执行,是异步执行。要用一个自动释放池
在里面判断,第一次和加载大数据之后都要判断请求释放被取消。如果没有用gcD 把下载后的图片调度到主线程,用block返回。在外面的viewcontroller是主线程就可以直接操作ui控件。
总结 主要是在DAO 中 发送请求 (ASIHttpRequest 在发送请求是异步,在接收数据回到主线程 在viewcontroller 中的block接收数据,此时在viewcontroller中可以处理数据。在下载图片,是自定义NSOperation 也是这样的。下载完成 block 返回赋图片的值。
2:在首页和我的资料 的微博数据的布局是一样的。
1:实体类 微博类(status) 用户类(user) ——》status中持用user 是一对一,不可能循环持有。 循环持用( //循环引用要具备2个条件
//1:两个类相互持有并且都是retain 2;两个对象相互引用。)微博和用户类只满足一个条件相互持有都是retain。不满足两个对象相互引用,
2:dao类: 其中 在ASIHttpRequest中调用的时候自己retain和加载完成和失败的release.
1:封装一个方法,通过不同URL 用ASIHttpRequest向新浪微博发送请求,然后在代理中用sbjson中,解析数据,用block放回 block的参数(返回的数据,返回错误的信息,分页数,总数)
2:分别提供两个方法,一个是首页发送信息,一个是我的关注的首页,两个方法。
内部调用(asiHttpRequest向新浪微博发送请求)
3:在我的首页和资料只是头部不同,其他的数据相同
3: 显示信息自定义cell(原理说明:1:每当由一个cell ,进入视野的时候,都会调用 tableview的代理方法,算出来cell 的高度,存入到缓存,然后创建和循环使用cell的时候在调整cell内部的layOutSubiview的方法调整contentview的大小
1:在cell Init方法的时候 加载所有的控件的位置,cell从索引中取出来对应的高度——》在layoutsubview 调整cell内部的高度和cell的高度。
2:其中cell内部高度是怎样布局了。
2.1》因为各个要重新给各个控件进行重新定位,各个控件的高度要根据内容来确定高度。一:通过内容来计算高度的方法:sizeWithFont:[UIFont systemFontOfSize:kScreenNameSize] constrainedToSize
其中label的numbeofline 要设置为0 可以自动换行 ,初始化控件要设则显示内容的空间的字体。
2.2 用一个statuFrame实体类:来记录 每个控件的位置和cell的总高度,其中记录的高度是readonly
2.3:在计算各个控件的位置,按照图的顺序,下一个以上一个为标准来计算
分几种情况,分别记录cell的高度。
2.4在初始化微博的数据,把输入微博的数据传入到statuFrame中得到各个控件的位置和cell的高度。
流程 1:初始化status ,给status中所有的字段进行赋值,2:然后在实例化self.statuFrame=[statuframe alloc] initwithStatu:statu] autorelease];
然后在statuFrame内部,拿到微博的数据进行布局,布局的原则,下一个以上一个来计算包括高度。这样思路清晰。
这样通过内容就回自动算出来cell的高度,记住在初始化cell内部控件的时候,自定的字体和要显示换行,和statuframe算出的高度字体要一致。
其中图片的cell中UIImageview 要暴露出去,以便异步下载使用进行复值。
3:在viewcontroller中获取信息之后,在调整高度的时候,就可以获取cell的对应高度,在创建cell的时候,cell中暴露出一个@property (nonatomic,retain) Staus.重写setStatus方法,进行给各个控件赋值。在调用layoutSubview中的时候,再次使用status中statusFrame,就可以调整位置。
我的资料,:数据和首页的微博内容格式一致,所以可以直接重写父类调用公布的方法。
在重写父类公布的公用方法——》调用不同方法,返回的数据相同
、
1;在开始发送请求的时候把MBProgreessHud 展示模板,在block返回中隐藏模板。
2:在是同tableview 使用的是mvc模式 1:控制器只需要改变数据模型,然后更形界面,而不是直接修改界面的数据。
3:在tableview上头部加headview 的信息。头部信息的uiview是自定义
1:初始view的时候,加入子控件,并且指定子控件的fame ;指定的时候也是下一个的fram根据上一个控件的fram来指定。
2:我的关注的信息,来源要和下面的信息一致,即在下面block返回数据的时候,再次公布一个返回数据的方法,让子类去接收,然后子类拿到数据后,就可以设置头部信息。头部信息设置完成后,。
3:由于我的首页中可以跳转到“我的粉丝页面”,和“我的关注”页面,其中在头部要暴露出一个视图控制器属性,进行切换。,然后监听头部view的点击事件,把对应“粉丝”和“关注”的视图控制,押入到当前导航控制器。由于“粉丝”和“关注”视图控制器的中每一行,都可以跳到“自定的粉丝页面”,把粉丝页面押入进去。——》每次押入一个控制器,的时候,都是重新创建一个视图控制器,放入进去。