美文网首页iOS入门
03.项目实战 百思不得姐 推荐标签,关注/登陆界面搭建

03.项目实战 百思不得姐 推荐标签,关注/登陆界面搭建

作者: Liwx | 来源:发表于2016-01-25 00:36 被阅读442次

    @(iOS 项目实战)[项目实战]


    目录

    • 新帖登录界面运行效果
    • 1.新帖
      • 推荐标签搭建
      • 推荐标签相关知识点
    • 2.关注和登陆界面
      • 使用xib搭建关注界面
      • 使用xib搭建登陆界面
      • xib使用注意

    新帖登录界面运行效果

    1.新帖

    推荐标签搭建

    • 1.在push方法中统一设置跳转到非根控制器隐藏tabBar,必须在push前隐藏tabBar
    // ----------------------------------------------------------------------------
    // 重写pushViewController:方法,在跳转前统一设置返回按钮
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        // ------------------------------------------------------------------------
        // 1.判断如果不是根控制器,则设置viewController控制器返回按钮
        if (self.childViewControllers.count > 0) {
            // 必须在push前隐藏tabBar
            viewController.hidesBottomBarWhenPushed = YES;
            
            viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem backItemWithImage:[UIImage imageNamed:@"navigationButtonReturn"] highImage:[UIImage imageNamed:@"navigationButtonReturnClick"] target:self action:@selector(back) title:@"返回"];
        }
        
        [super pushViewController:viewController animated:animated];
    }
    
    • 2.设置推荐标签的标题两种方式, self.title = @"标题文字",必须在非根控制器的时候才能这么使用,否则有问题.
    // 方式一
    self.navigationItem.title = @“推荐标签”;
    // 方式二,只有在非根控制器的时候才能这么使用,否则有问题.
    self.title = @“推荐标签”;
    
    • 3.获取推荐标签网络数据

      • 接口文档
      • 1.创建请求回话管理者
      • 2.设置响应体的数据格式,添加@"text/html"(可选)
      // ------------------------------------------------------------------------
      // 2. 设置响应体的数据格式,添加@"text/html"
      AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
      serializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
      manager.responseSerializer = serializer;
      
      • 3.拼接请求参数

      • 4.发送请求,请求广告数据

        • 4.1 获取广告数据 ,返回的广告数据是数组,有[],所以要用lastObject取出数据
        • 4.2 字典转模型 mj_objectWithKeyValues:方法作用是将字典转换成对应的模型
        • 4.3 设置广告界面的数据,返回数据中有广告图片的尺寸
          注意广告界面bug: 服务器返回的图片宽度有可能为0,需判断宽度是否为0,否则会出现NaN崩溃错误,原因是因为除以0, 不等于0才可以除.
        • 4.4 添加点击手势,点击图片跳转到广告页
          • 默认UIImageView是不能与用户交互的,必须先设置userInteractionEnabled属性为YES;
      • 参考代码

        // ----------------------------------------------------------------------------
        // 请求广告数据
        - (void)loadAdData
        {
            // ------------------------------------------------------------------------
            // 1.创建请求回话管理者
            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            
            // ------------------------------------------------------------------------
            // 2. 设置响应体的数据格式,添加@"text/html"
            AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
            serializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
            manager.responseSerializer = serializer;
            
            // ------------------------------------------------------------------------
            // 3.拼接请求参数
            NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
            parameters[@"code2"] = code2;
            
            // ------------------------------------------------------------------------
            // 4.请求广告数据
            [manager GET:@"http://mobads.baidu.com/cpro/ui/mads.php" parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                // 判断取回来的数据是否正确
                
                // 4.1 获取广告数据 ,返回的广告数据是数组,有[],所以要用lastObject取出数据
                NSDictionary *adDict = [responseObject[@"ad"] lastObject];
                
                // 判断是否请求到数据,如果没有数据,则退出
                if (adDict == nil) {
                    return;
                }
                // 4.2 字典转模型 mj_objectWithKeyValues:方法作用是将字典转换成对应的模型
                WXAdItem *adItem = [WXAdItem mj_objectWithKeyValues:adDict];
                self.adItem = adItem;
                
                // 4.3 设置广告界面的数据,返回数据中有广告图片的尺寸
                CGFloat w = screenW;
                // NaN:除以0, 不等于0才可以除
                if (adItem.w) {
                    
                    // 计算宽高比例
                    CGFloat h = screenW / adItem.w * adItem.h;
                    UIImageView *adImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, w, h)];
                    [adImageView sd_setImageWithURL:[NSURL URLWithString:adItem.w_picurl]];
                    [self.adView addSubview:adImageView];
                    adImageView.userInteractionEnabled = YES;
                    
                    // 4.4 添加点击手势,点击图片跳转到广告页
                    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
                    [adImageView addGestureRecognizer:tap];
                }
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                NSLog(@"%@", error);
            }];
          
        }
      
    • 4.搭建推荐标签界面
      • 1.加载xib中cell的两种方式

        • NSBundle方式(必须在xib绑定标识才能循环利用cell)
          xib绑定标识.png
        static NSString * const ID = @"cell";
        // 从缓冲池获取cell
        WXSubTagCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        if (cell == nil) {
            // 从xib创建cell
            cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([WXSubTagCell class]) owner:nil options:nil] lastObject];
        }
        
        • 注册方式(使用self.tableView registerNib方法注册,可以不用在xib中绑定标识)
        // 在viewDidLoad方法中注册cell
        [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([WXSubTagCell class]) bundle:nil] forCellReuseIdentifier:ID];
        
      • 2.展示cell数据

      • 3.处理cell中的细节

        • 圆形头像处理
          • 方式一: 在awakeFromNib设置头像的圆角半径layer.cornerRadius并裁减masksToBounds.
            - (void)awakeFromNib {
                self.iconImageView.layer.cornerRadius = self.iconImageView.bounds.size.width * 0.5;
                self.iconImageView.layer.masksToBounds = YES;
            }
        
          - 方式二: 在xib中使用KVC设置(不建议使用)
        
    xib中设置KVC.png

    - 方式三: 先裁减图片,再显示到iconImageView
    - 订阅数(子标题)处理
    - 处理订阅数(超过万的时候处理,让小数点如果是.0,不显示.0,通过字符串替换,将.0替换成空串)
    - cell分割线处理(具体如下操作)

    • 5.cell分割线处理
      • 方式一: 用UIView自定义分割线.

      • 方式二: 利用系统tableView的separatorInset属性.

      • 处理系统分割线(分割线靠最左边): 设置cell的layoutMargins属性,只支持iOS8以上.

      • 方式三: 重写cell的setFrame实现(常用)

        • 1.取消系统的样式separatorStyle为UITableViewCellSeparatorStyleNone
        • 2.设置tableView的背景色为分割线的颜色,目的是为了让露出的背景部分充当分割线.
        • 3.重写cell的setFrame方法,内部需先调用[super setFrame:frame];让frame的高度属性减去一个值,比如减去1,如果要让分割线更宽,减去的值为更大值即可.
        • cell的尺寸和位置是在每次刷新表格/表格要显示的时候,先把所有cell位置全部计算出来.当cell要显示的时候,会从刚刚计算好的位置取出来给cell赋值.
      • 方式三实现参考代码

    // WXSubTagViewController.m中取消tableView原本的分割线,设置tableView的背景色为分割线颜色
    // ----------------------------------------------------------------------------
    // 设置分割线,需在cell内部将cell高度-1,这样让漏出的背景充当分割线
    - (void)setupSeparatorLine
    {
        // 分割线: 1.自定义分割线 2.利用系统属性 3.重写cellsetFrame
        // 4.取消系统的分割线
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        // 设置tableView背景色,之后将cell的高度-1,漏出的背景充当分割线
        self.tableView.backgroundColor = WXColor(206, 206, 206);
    }
    
    // 在WXSubTagCell.m中
    // ----------------------------------------------------------------------------
    // 重写setFrame方法,目的是为了让分割线占据屏幕整个宽度
    - (void)setFrame:(CGRect)frame
    {
        // 露出1pt充当背景分割线,
        frame.size.height -= 1;
        [super setFrame:frame];
    }
    
    • 6.AFN取消请求业务

      • 发送请求前弹出指示器
      • .在viewWillDisappear方法中隐藏指示器
      • 在viewWillDisappear方法中使用AFHttpSessionManager的tasks属性(tasks是数组), 让数组里面的每个任务都调用cancel方法取消任务.
      • viewWillDisappear方法内部实现参考代码
        // ----------------------------------------------------------------------------
        // 取消网络请求任务, 控制器的view即将消失的时候调用
        - (void)viewWillDisappear:(BOOL)animated
        {
            [super viewWillDisappear:animated];
            
            // 取消所有网络任务
            [self.mgr.tasks makeObjectsPerformSelector:@selector(cancel)];
            
            // 隐藏指示器
            [SVProgressHUD dismiss];
        }
      

    推荐标签相关知识点

    • 裁减图片步骤(存在锯齿)

      • 1.开启位图上下文(自适应位图上下文比例)
      • 2.贝塞尔曲线描述裁减路径
      • 3.设置裁减区域
      • 4.绘图
      • 5.从上下文获取才叫好的图片
      • 6.关闭上下文
      • 7.用抗锯齿分类设置圆形图片抗锯齿(抗锯齿实现原理: 生成1像素的图形边框)
      • 裁减图片参考代码
      // 1.开启位图上下文(自适应位图上下文比例)
      UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
      
      // 2.贝塞尔曲线描述裁减路径
      UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
      // 3.设置裁减区域
      [path addClip];
      // 4.绘图
      [image drawAtPoint:CGPointZero];
      // 5.从上下文获取裁剪好的图片
      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
      // 6.关闭上下文
      UIGraphicsEndImageContext();
      
      // 7.用抗锯齿分类设置圆形图片抗锯齿(抗锯齿实现原理: 生成1像素的图形边框)
      self.iconImageView.image = [newImage imageAntialias];
      
    • tableView优化

      • 帧数小于45就会出现明显感觉卡顿现象
      • iOS9不需要担心圆角使帧数降低
    • 观察刷新帧数工具: Core Animation工具(只能在真机上才能观察)
      打开Core Animation


      打开Core Animation.png

      Xcode的工具软件,选中Core Animation


      Xcode的工具软件.png

      Core Animation界面


      Core Animation界面.png

    2.关注和登陆界面

    使用xib搭建关注界面

    • 1.UILabel文字换行

      • 1.UILabel在xib实现换行按option + 回车.
      • 2.代码实现换行只需在显示的文本添加\n
        即可换行.
    • 2.自动布局关注界面

      • 1.设置立即登陆注册按钮为Custom类型,并设置按钮普通/高亮状态显示的内容.
    • 3.绑定xib的管理类,并设置xib的view为控制器的view

    • 关注界面效果图


      关注界面效果图.png

    使用xib搭建登陆界面

    • 1.划分结构: 采用占位视图思想(3部分,顶部,中间,底部)
      xib设计图
      xib设计图.png

    运行效果图,橙色背景色只是为方便分析而添加的.

    运行效果图.png
    • 2.设置背景图片

    • 3.布局顶部关闭和注册帐号按钮

      • 1.设置注册帐号按钮普通/选中状态的文字.
    • 4.自定义中间登陆LoginRegisterView

      • 1.添加和帐号和密码的文本框背景一样尺寸的view,作为占位视图

      • 2.添加ImageView到占位视图view中,

      • 3.设置帐号密码文本框左右间距

        • 修改文本框样式Border Style


          修改文本框样式Border Style.png
      • 4.设置登陆按钮

        • 1.通过代码或使用xib设置(xib中KVC方式设置)设置圆角半径并裁减.
        • 2.在awakeFromNib方法中获取按钮的背景图片,并重新生成拉伸中间1x1的图片.
          获取按钮当前状态背景图片: currentBackgroundImage属性获取当前按钮状态的背景图片.
      • 5.在同一个xib描述两个不同的view

        • 1.提供一个快速创建登陆view的类方法
        • 2.提供一个快速创建注册view的类方法


          xib描述两个不同的view.png
      • 6.登陆和注册界面动画

        • 1.通过修改约束来实现修改登陆和注册界面的位置,从xib中将最左边的间距拖入代码成为属性.

          约束拖线关联.png
        • 2.点击注册按钮实现自动布局动画参考代码

          • 更新约束强制刷新方法layoutIfNeeded,如果没有调用layoutIfNeeded方法,不会立即更新.
          // ----------------------------------------------------------------------------
          // 注册按钮点击
          - (IBAction)registerOrLogin:(UIButton *)sender
          {
              // 1.切换选中状态
              sender.selected = !sender.isSelected;
              
              // 2.更新约束
              self.leftMargin.constant = self.leftMargin.constant == 0 ? -screenW : 0;
              
              // 3.执行动画(更新约束动画刷新方法layoutIfNeeded)
              [UIView animateWithDuration:0.25 animations:^{
                  // 3.1 强制刷新
                  [self.view layoutIfNeeded];
              }];
              
          }
      
      • 7.通过xib创建的控件,加载时默认是xib的位置尺寸.从xib加载的view必须再重新设置frame来适配不同屏幕.
        • 1.不要在viewDidLoad方法中重新设置frame,最好在viewDidLayoutSubviews方法中重新设置xib中view的frame.
    • 5.底部快速登陆界面

      • 1.布局底部三个第三方登陆按钮.
      • 2.自定义按钮,调整按钮的位置,让图标显示在上面,标题显示在下面.
        • 投机方式: 通过改变按钮的imageView和titleLabel内边距(不建议使用)
        • 自定义FastLoginButton重写layoutSubviews重新布局按钮的子控件,图片放置顶部,标题放置底部.
          • 重新计算文字的宽度,在给titleLabel宽度赋值,否则会出现文字用…显示.使用[self.titleLabel sizeToFit]就能解决.
      • 3.设置快速登陆UILabel和左右两边的线条UIImageView,设置UIImageView的contentMode,左边线设置为Right模式,右边先设置为Left模式.


        设置UIImageView的contentMode.png

    xib使用注意

    • 1.从xib加载的view必须要重新设置位置和尺寸.

    • 2.不要在viewDidLoad方法中重新设置frame,最好在viewDidLayoutSubviews方法中重新设置xib中view的frame.

    相关文章

      网友评论

        本文标题:03.项目实战 百思不得姐 推荐标签,关注/登陆界面搭建

        本文链接:https://www.haomeiwen.com/subject/thorkttx.html