IOS开发基础—qq表情排列重构

作者声明

因跟人能力问题,文中不免有错误之处,欢迎各位读者交流,批评,指正!

摘要

在上文的基础上,重构“qq表情排列”,主要的原则就是:将公共代码提取到一个方法中,供其它方法调用,不同的地方通过传递参数来实现。主要包括添加表情代码和排序代码。

实例

viewController h代码

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

- (IBAction)sortImages:(UISegmentedControl *)sender;

#pragma mark 待改进1:是否可以通过其它方法将其省略?
// 仅仅是为了在加号的监听事件调用的方法中得到segment的值。
@property (weak, nonatomic) IBOutlet UISegmentedControl *segment;


@end

viewController m代码

//
//  ViewController.m
//  qq表情排序(按老师的思路重写一遍)
//
//  Created by dqw on 15/5/7.
//  Copyright (c) 2015年 itcast. All rights reserved.
//

#import "ViewController.h"

#define KImageWH 50 // 每个图片的长宽
#define No 10       // 初始化图片的个数。

@interface ViewController ()

@end



@implementation ViewController

#pragma mark 1. 在view加载完毕后加载图片。
- (void)viewDidLoad {

    [super viewDidLoad];

    // 加载图片。
    for (int i = 0; i < No; i++) {

        [self addImageWithNo:i AtIndex:i + 1 isInitial:YES];

    }

    // 加载后按2列排序。
    [self sortImagesWithCount:No InColumns:2];

}

#pragma mark 2. 定义加载单个图片方法
- (void)addImageWithNo:(int)imageNo AtIndex:(int)index isInitial:(BOOL)isInitial
{
    NSString *newImageName = [NSString stringWithFormat:@"%d.png",imageNo];

    UIImage *newImage = [UIImage imageNamed:newImageName];

    // 定义父类指针。
    UIView *newImageView;

#pragma mark 注意点1:最后一个是button类型。
    // 创建最后一个加号(button类型)
    if ((imageNo == (No -1)) && isInitial ) {

        newImageView = [[UIButton alloc]init];

#pragma mark 重点1:多态。
        // 多态,强制类型转换后才能调用子类方法。
        UIButton *temp = (UIButton *)newImageView;

        [temp setImage:newImage forState:UIControlStateNormal];

        // 为按钮添加监听事件。
        [temp addTarget:self action:@selector(addImage) forControlEvents:UIControlEventTouchUpInside];

    }
    // 创建非最后一个加号,或者随机图片。
    else
    {
        newImageView = [[UIImageView alloc]init];

        // 多态,强制类型转换后才能调用子类方法。
        UIImageView *temp = (UIImageView *)newImageView;

        temp.image = newImage;

    }

#pragma mark 待改善1:是否可以简化合成
#pragma mark 疑问1:仔细研究这三种插入方法。
    // 初始化和随机插入两种情况,该部分要考虑一下是否可以合成。
    if (isInitial) {
        [self.view insertSubview:newImageView atIndex:index];
    }
    else{

        [self.view insertSubview:newImageView belowSubview:self.view.subviews[index]];
    }

}

#pragma mark 3. 定义图片排序方法
- (void)sortImagesWithCount:(int)count InColumns:(int)column
{

#pragma mark 注意点2:动画的位置。
    // 动画放在这里更合适,因为位置值的改变就这这里发生。
    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:1.0];

    // 图片y方向的起始位置和间距。
    CGFloat startY = 10;
    CGFloat distanceY = 50;
    CGFloat startX;
    CGFloat x;
    CGFloat y;

    startX = (self.view.frame.size.width -column * KImageWH) / (column + 1);

    // 多态,父类指针。
    UIView *tempView;

    for (int i = 0; i < count; i++) {

        x = startX + (startX + KImageWH) * (i % column);

        y = startY +  (distanceY + KImageWH) * (i / column);

        tempView = self.view.subviews[i + 1];

        tempView.frame = CGRectMake(x, y, KImageWH, KImageWH);

    }

    [UIView commitAnimations];

}

#pragma mark 4. 监听segment的值。
- (IBAction)sortImages:(UISegmentedControl *)sender {

//    [UIView beginAnimations:nil context:nil];
//    
//    [UIView setAnimationDuration:1.0];

    int column = sender.selectedSegmentIndex + 2;

    // 更新个数。
    int count = self.view.subviews.count;

    [self sortImagesWithCount:count -1  InColumns:column];

//    [UIView commitAnimations];
}

#pragma mark 5. 定义添加随机图片的方法(供加号监听事件调用)
- (void)addImage
{
#pragma mark 待改善2:是否可以合成到添加图片方法中?
#pragma mark 疑问2:监听事件调用该方法时如果该方法有参数则如何传递参数?

    int imageNo = arc4random() % 9;

    int count = self.view.subviews.count;

    // index参数和插入的方法对应。
    [self addImageWithNo:imageNo AtIndex:count - 1  isInitial:NO];

    int column = _segment.selectedSegmentIndex + 2;

    // 注意此处的count,因为已经add过了,所以此处count不-1.
    [self sortImagesWithCount:count  InColumns:column];
}

@end

重点 难点 注意点

  1. 如KImageWH,宏定义的时候第一个字目写K,可以用后面的WH表示一个单词width,但是一般宏名是全大写,单词简化也是取单词前缀。
  2. 将表情的添加方法和表情的排序方法提取,体会这样的模块化思想,更加灵活。
  3. 多态:用同样的父类uiview指针指向子类uiimageview和uibutton,但是在调用子类方法时,要强制类型转换。
  4. 动画的位置,避免重复写,放在动画发生的代码块中。
  5. 实施的更新subviews的个数。

疑问

  1. 为一个控件添加监听事件时,所调用的方法如果有参数,则该参数如何传递进去??
  2. 三种插入方法的区别?

待完善内容

  1. .h文件待改进1:@property segment 是否可以省略?
  2. 单词的缩写规则。
  3. .m文件待改进1,2:代码进一步合并简化。
  4. 添加storyboard,还有以前的。
  5. 这一部分的视频和实例代码还没有看。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值