IOS開發基礎—簡單的qq表情排列app
作者宣告
因個人能力問題,文中不免有錯誤之處,歡迎各位讀者交流,批評,指正!
摘要
本文通過一個例項:將qq表情按不同的列排序,並實現表情新增功能,學習控制元件segment的基本用法。
例項
viewController h程式碼
//
// ViewController.h
// 簡單的表情排列app
//
// Created by dqw on 15/5/7.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *iconsView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segment;
- (IBAction)setColumns:(UISegmentedControl *)sender;
@end
viewController m程式碼
//
// ViewController.m
// 簡單的表情排列app
//
// Created by dqw on 15/5/7.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
{
// 定義供多個方法使用的成員變數。
NSArray *_iconViews;
CGFloat _width;
CGFloat _height;
CGFloat _x;
CGFloat _y;
NSUInteger _count; // 表情圖片的個數。
int _n; // 新增的表情個數。
}
@end
@implementation ViewController
#pragma mark 1. 初始化載入表情。
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化。
_n = 0;
// 給_width和_height賦值。
UIImage *icon = [UIImage imageNamed:@"0.png"];
_width = icon.size.width;
_height = icon.size.height;
// 定義變數。
NSString *iconName;
UIImageView *iconView;
for (int i = 0; i < 10; i++) {
// 建立圖片例項。
iconName = [NSString stringWithFormat:@"%d.png",i];
UIImage *icon = [UIImage imageNamed:iconName];
// 建立圖片檢視。
iconView = [[UIImageView alloc]init];
// 定義各圖片控制元件的位置。
_x = (_iconsView.frame.size.width - _width * 2) * 0.5 + _width * (i % 2);
_y = _height * (i / 2);
// 設定圖片控制元件
iconView.frame = CGRectMake(_x, _y,_width,_height);
iconView.image = icon;
if (i == 9) {
#pragma mark 重點:uiimageview不能呼叫addtargetxx方法。
// 新增uicontrol型別的控制元件,因為uiimageview型別的控制元件不可以新增監聽事件。addtatget不是uiview的方法,而是其子類uicontrol的方法。
UIButton *addBut = [[UIButton alloc]init];
addBut.frame = CGRectMake(_x, _y,_width,_height);
[addBut setBackgroundImage:icon forState:UIControlStateNormal];
[_iconsView addSubview:addBut];
}
else{
// 新增圖片控制元件。
[_iconsView addSubview:iconView];
}
}
// 提取圖片框中的所有子控制元件到陣列內。注意體會:@property(nonatomic,readonly,copy) NSArray *subviews;
_iconViews = _iconsView.subviews;
_count = _iconViews.count;
#pragma mark 為最後一個button控制元件新增監聽事件。
// 為最後一個控制元件新增監聽事件。
[_iconViews[_count -1] addTarget:self action:@selector(addIcon) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark 2. 定義監聽事件呼叫的新增表情方法。
- (void)addIcon{
// 更新_count數值。
_iconViews = _iconsView.subviews;
_count = _iconViews.count;
#pragma mark 重點2:不能通過陣列元素來訪問frame變數。
// 因為不能通過陣列元素得到frame屬性。所以通過一個相同型別的指標temp來得到其frame屬性。
UIImageView *temp = _iconViews[_count -1];
UIImageView *temp1 = [[UIImageView alloc]init];
// 深刻體會。
temp1.frame = temp.frame;
NSString *iconName = [NSString stringWithFormat:@"%d.png",(_n++ % 9)];
temp1.image = [UIImage imageNamed:iconName];
#pragma mark 重點3:insert below 。
// 在最後一個元素前面插入新元素,注意用的是below。
[_iconsView insertSubview:temp1 belowSubview:_iconViews[_count - 1]];
// 插入新元素後更新_count值。
_iconViews = _iconsView.subviews;
int index = _iconViews.count -1;
// 為了得到列數,引入了segment成員變數。
int column = _segment.selectedSegmentIndex + 2 ;
// 更改最後一個元素的位置。
_x = (_iconsView.frame.size.width - _width * column) * 0.5 + _width * (index % column);
_y = _height * (index / column);
temp.frame = CGRectMake(_x, _y, _width, _height);
}
#pragma mark 3. 按列排序。
- (IBAction)setColumns:(UISegmentedControl *)sender{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
// 獲取列數。
int column = sender.selectedSegmentIndex + 2;
// 更新_count。
_iconViews = _iconsView.subviews;
_count = _iconViews.count;
#pragma mark 重點3:不能通過陣列元素來訪問frame變數。
// 此處需注意:不能通過陣列訪問subview的frame成員變數(即_iconView[i].frame 是錯誤的表達,編譯不通過),所以要新建一個臨時的UIImageView temp 來作為過渡。個人認為:可能是因為_iconView是個不可變陣列.但是把其中的元素提取出來後,更改其屬性,實際的元素屬性的確被更改了,這是不是代表著該陣列是深複製的不可變陣列(uiview的subviews變數是用copy修飾的),但是其中的元素時淺複製,所以單獨更改後,真實的元素屬性也被更改了。雖然temp是通過賦值得到的元素,但是temp和xx[]都是指標,所以都指向的時同樣的元素。
#pragma mark 疑問1 subviews copy修飾??
// @property(nonatomic,readonly,copy) NSArray *subviews;還不是理解?
UIImageView *temp;
for (int i = 0; i < _count; i++) {
// 對應temp。
temp = _iconViews[i];
// 讓圖片位於左右的中間,注意取餘數和取商的用法。
_x = (_iconsView.frame.size.width - _width * column) * 0.5 + _width * (i % column);
_y = _height * (i / column);
temp.frame= CGRectMake(_x, _y, _width, _height);
}
[UIView commitAnimations];
}
@end
重點 難點 注意點
- uiimageview不能呼叫addtarget方法,將最後的加號圖片設定為uibutton型別。
- 在uiimageview中最後一個subview前面插入subview ,是用的below,而不是above。
- 不能通過陣列訪問subview的frame成員變數(即_iconView[i].frame 是錯誤的表達,編譯不通過),所以要新建一個臨時的UIImageView temp 來作為過渡。個人認為:可能是因為_iconView是個不可變陣列.但是把其中的元素提取出來後,更改其屬性,實際的元素屬性的確被更改了,這是不是代表著該陣列是深複製的不可變陣列(uiview的subviews變數是用copy修飾的),但是其中的元素時淺複製,所以單獨更改後,真實的元素屬性也被更改了。雖然temp是通過賦值得到的元素,但是temp和xx[]都是指標,所以都指向的時同樣的元素。
- 既然是排列,類似於矩陣,為了得到其行數和列數,用取餘數和取商是個很好的方法。
疑問
- @property(nonatomic,readonly,copy) NSArray *subviews;還不是理解?其中的copy??
待完善的內容
- 更深入瞭解一下segment的用法。
相關文章
- ISO開發基礎—簡單的圖片瀏覽appAPP
- iOS 基礎開發技巧 (一)iOS
- iOS開發之顯示微博表情iOS
- OS開發基礎——多執行緒的簡單應用執行緒
- 【IOS開發基礎系列】Cocoa基礎專題iOS
- iOS開發小記-基礎篇iOS
- iOS 藍芽開發·基礎篇iOS藍芽
- iOS 開發之 ReactiveCocoa(基礎)iOSReact
- iOS開發基礎107-iOS直播iOS
- iOS藍芽4.0開發基礎教程iOS藍芽
- IOS開發 製作簡單的計算器iOS
- iOS開發簡單的音訊播放器iOS音訊播放器
- 影視APP開發基礎功能詳解APP
- app,小程式開發基礎知識APP
- 基於vue的簡單流程圖開發Vue流程圖
- 玩轉iOS開發:iOS 11 新特性《基於文件管理的App》iOSAPP
- IOS 特定於裝置的開發:Core Motion基礎iOS
- iOS開發基礎篇--NSNotificationCenter使用小結iOS
- IOS-Swift開發基礎——檔案管理iOSSwift
- iOS開發基礎135-Core DataiOS
- iOS開發基礎117-HybridiOS
- Android Studio1.4.x JNI開發基礎 - 簡單例項Android單例
- iOS好用的分類工具 讓開發更簡單 WHKitiOS
- iOS開發 -- C語言基礎8(指標)iOSC語言指標
- iOS開發Objective-C基礎之──多型iOSObject多型
- iOS開發系列--C語言之基礎知識iOSC語言
- iOS開發基礎136-防暴力點選iOS
- iOS開發基礎142-廣告歸因iOS
- iOS開發基礎144-逐字列印效果iOS
- iOS開發基礎146-深入解析WKWebViewiOSWebView
- iOS開發基礎148-ABM vs MDMiOS
- iOS開發之簡單音訊播放器iOS音訊播放器
- [Android基礎]WebView的簡單使用AndroidWebView
- mybatis入門基礎(二)----原始dao的開發和mapper代理開發MyBatisAPP
- 簡單易懂KVC基礎篇
- 鳥巢如何更簡單更快的開發NativeAppAPP
- 基於ThinkPHP3.2.3開發的簡單cms(已開源)PHP
- iOS 基於FMDB簡單封裝iOS封裝