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. 這一部分的視頻和實例代碼還沒有看。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章