I os 04
- 2. 內容⼤大綱
• Objective-C 陣列 (NSArray, NSMutableArray)
• QV008:陣列圖⽚片變換動畫
• UIPickerView 與 Delegate 代理⽅方法
• QV009:以程式⽅方式產⽣生
• QV010:基本,以 xib ⽅方式使⽤用
• QV011:UIPickerView + UIDatePicker
• QV012:UIPickerView 多個區段選擇
• 其他 UIPickerView 特殊技巧與範例
• QV105:相依關聯的 Picker
• QV106:頭尾相連的 Picker
• QV107:吃⾓角⼦子⽼老⻁虎
• Samples:Pickers Demo
- 4. NSArray (1/2)
• 可以把任何物件當做元素置⼊入
• 可依照順序存取
• 可直接存取指定位置元素
• 索引由 0 開始
• 元素裡可以混合相異的類別實體
• 可以多次含有相同的物件
• 不可以把 nil 做為元素
- 6. (1) 陣列物件的初始化及產⽣生
• -(id) array
• -(id) arrayWithObject: (id) anObject
• -(id) initWithObjects: (id) firstObj, ......
• -(id) initWithObjects: (id *) objects count:
(NSInteger) count
• -(id) initWithArray: (NSArray *) anArray
• -(id) initWithArray: (NSArray *) array copyItems:
(BOOL) flag
- 7. (2) 陣列物件的存取
• -(NSUinteger) count
• -(NSUinteger) indexOfObject: (id)anObject
• -(id) objectAtIndex: (NSUInteger) index
• -(id) lastObject
• -(void) getObjects: (id) aBuffer
• -(NSArray *) subarrayWithRange: (NSRange)
range
- 8. (3) ⽐比較
• -(BOOL) isEqualToArray: (id)anObject
• -(id) firstObjectCommonWithArray:
(NSArray *) otherArray
- 9. (4) 增加新元素
• -(NSArray *) arrayByAddingObject:
(id)anObject
• -(NSArray *)
arrayByAddingObjectsFromArray:
(NSArray *)anArray
- 10. (5) 排序
• -(NSArray *) sortedArrayUsingSelector:
(SEL) comparator
• -(NSArray *) sortedArrayUsingFunction:
(NSInteger (*)(id,id,void*)) comparator
context: (void *)context
- 11. (6) 對元素的訊息傳送
• -(void) makeObjectsPerform:
(SEL)aSelector
• -(void) makeObjectsPerform: (SEL)
aSelector withObject: (id) anObj
- 12. (7) 字串元素的操作
• - (NSString *) componentsJoineByString:
(NSString *) separator
• - (NSArray *) pathsMatchingExtensions:
(NSArray *) filterTypes
- 13. (8) 檔案的輸出與輸⼊入
• -(NSString *) description
• -(id) initWithContentsOfFile: (NSString
*)aPath
• -(BOOL) writeToFile: (NSString *) path
atomically:(BOOL)flag
- 17. (2) 陣列的追加與置換
• -(void) addObject: (id)anObject
• -(void) addObjecsFromArray:
(NSArray *)otherArray
• -(void) insertObject: (id)anObject atIndex:(NSUInteger)
index
• -(void) replaceObjectAtIndex: (NSUInteger)index
withObject:(id)anObject
• -(void) setArray: (NSArray *)otherArray
• -(void) exchangeObjectAtIndex: (NSUinteger)idx1
withObjectAtIndex:(NSUInteger) idx2
- 18. (3) 物件的刪除
• -(void) removeAllObjects
• -(void) removeLastObject
• -(void) removeObjectAtIndex: (NSUInteger)index
• -(void) removeObjectsInRange: (NSRange)aRange
• -(void) removeObject: (id)anObject
• -(void) removeObjectsInArray:
(NSArray *)otherArray
- 19. (4) 排序
• -(void) sortUsingSelector: (SEL)comparator
• -(void) sortUsingFunction:(NSInteger (*)
(idid,void *))compare
context:(void *)context
- 21. 列舉⼦子 NSEnumerator
• 對被存放在陣列、集合、字典等集合中的元素物
件,可以依序存取的系統
• Objective-C 2.0 後多被 for ...in 取代
• ⽅方法......
• -(id) nextObject
• -(NSArray *) allObjects
• -(NSEnumerator *) objectEnumerator
• -(NSEnumerator *) reverseObjectEnumerator
- 25. ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *myImages = [NSArray arrayWithObjects:
[UIImage imageNamed:@"01.jpg"],
[UIImage imageNamed:@"02.jpg"],
[UIImage imageNamed:@"03.jpg"],
⽤用陣列定義
[UIImage imageNamed:@"04.jpg"], 多個圖檔
[UIImage imageNamed:@"05.jpg"],
[UIImage imageNamed:@"06.jpg"],
nil];
UIImageView *myAnimatedView = [[UIImageView alloc]
initWithFrame:CGRectMake(90, 100, 140, 140)];
myAnimatedView.animationImages = myImages;
myAnimatedView.animationDuration = 3.0;
myAnimatedView.animationRepeatCount = 0;
[myAnimatedView startAnimating];
動畫設定
[self.view addSubview:myAnimatedView];
}
- 32. #import "ViewController.h"
ViewController.m (1/2)
@implementation ViewController
@synthesize myPickerView, dataArray;
- (void)viewDidLoad
{ 寬度可調,但⾼高度固定
[super viewDidLoad];
myPickerView = [[UIPickerView alloc]
initWithFrame:CGRectMake(0, 0, 320, 240)];
myPickerView.dataSource = self; 物件的代理⼈人
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES; 其他屬性
// 決定清單陣列
NSArray *listArray = [[NSArray alloc] initWithObjects:
@"AAAAA", @"BBBBB", @"CCCCC", @"DDDDD", @"EEEEE", @"FFFFF", nil];
self.dataArray = listArray;
[self.view addSubview:myPickerView];
}
項⺫⽬目清單另外存放
****** 省略部分程式 ******
@end
- 33. ViewController.m (2/2)
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1; 共有幾個區段
}
-(NSInteger)pickerView:(UIPickerView *)pickView numberOfRowsInComponent:
(NSInteger)component
{
return [dataArray count]; 在區段內有幾個項⺫⽬目
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
// 此處尚無處理選取後的動作
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
return [dataArray objectAtIndex:row]; 各個項⺫⽬目的⽂文字
}
- 39. ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UIPickerViewDelegate,
UIPickerViewDataSource>
{
IBOutlet UILabel *message;
IBOutlet UIPickerView *myPickerView;
IBOutlet UIDatePicker *myDatePicker;
NSArray *dataArray;
}
@property (retain, nonatomic) IBOutlet UILabel *message;
@property (retain, nonatomic) IBOutlet UIPickerView *myPickerView;
@property (retain, nonatomic) IBOutlet UIDatePicker *myDatePicker;
@property (retain, nonatomic) NSArray *dataArray;
-(IBAction)dateSelect:(id)sender;
@end
- 40. ViewController.m
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
-(NSInteger)pickerView: (UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [dataArray count];
}
-(void)pickerView: (UIPickerView *) pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component
{
NSInteger r = [myPickerView selectedRowInComponent:component];
NSString *item = [dataArray objectAtIndex:row];
message.text = [NSString stringWithFormat:
@"%d, %d : %@", component, r, item];
}
-(NSString *)pickerView: (UIPickerView *)pickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
return [dataArray objectAtIndex:row];
}
- 44. ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>
{
IBOutlet UILabel *message;
IBOutlet UIPickerView *myPickerView;
NSArray *dataArray1, *dataArray2;
}
@property (retain, nonatomic) IBOutlet UILabel *message;
@property (retain, nonatomic) IBOutlet UIPickerView *myPickerView;
@property (retain, nonatomic) NSArray *dataArray1, *dataArray2;
@end
- 45. ViewController.m (1/3)
#import "ViewController.h"
@implementation ViewController
@synthesize message, myPickerView, dataArray1, dataArray2;
- (void)viewDidLoad
{
[super viewDidLoad];
!
myPickerView.dataSource = self;
myPickerView.delegate = self;
dataArray1 = [[NSArray alloc]
initWithObjects:@"AAA", @"BBB", @"CCC", @"DDD", nil];
dataArray2 = [[NSArray alloc]
initWithObjects:@"111", @"222", @"333", @"444", @"555", nil];
}
- 46. ViewController.m (2/3)
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{!
! return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:
(NSInteger)component
{!
if (component==0)
{ return [dataArray1 count]; }
else
{ return [dataArray2 count]; }
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
if(component==0)
{
return [dataArray1 objectAtIndex:row];
}
else
{
return [dataArray2 objectAtIndex:row];
}
}
- 47. ViewController.m (3/3)
- (void)pickerView: (UIPickerView *) pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{!
NSInteger n1 = [myPickerView selectedRowInComponent:0];
NSInteger n2 = [myPickerView selectedRowInComponent:1];
NSString *str1 = [dataArray1 objectAtIndex:n1];
NSString *str2 = [dataArray2 objectAtIndex:n2];
NSString *str = [[NSString alloc]
initWithFormat:@"%@ -- %@", str1, str2];
message.text = str;
}
- 48. 範例:
區段間有相依關聯
(左邊的改變會重設右邊的項⺫⽬目)
- 50. #import <UIKit/UIKit.h> ViewController.h
@interface ViewController :
UIViewController<UIPickerViewDelegate>
{
NSMutableDictionary *data;
NSArray *keys;
ViewController.xib
IBOutlet UIPickerView *picker;
IBOutlet UILabel *label;
}
@end
- 51. ViewController.m (1/4)
- (void)viewDidLoad
{
[super viewDidLoad];
[self prepareData];
}
- (void) prepareData
{
data = [[NSMutableDictionary alloc] init];
[data setValue:[NSArray arrayWithObjects:
@"可樂",@"沙⼠士",@"果汁",@"其他",nil] forKey:@"飲料"];
[data setValue:[NSArray arrayWithObjects:
@"蛋糕",@"糖果",@"巧克⼒力",@"其他",nil] forKey:@"甜點"];
keys =[[data allKeys] sortedArrayUsingComparator:
(NSComparator)^(id obj1,id obj2)
{
return [obj1 caseInsensitiveCompare:obj2];
}];
}
- 53. ViewController.m (3/4)
//設定滾輪顯⽰示的⽂文字
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
if (component==0)
{
return[keys objectAtIndex:row];
}
else
{
NSString *key = [keys objectAtIndex:
[thePickerView selectedRowInComponent:0]]; // 飲料或甜點
NSArray *array = [data objectForKey:key];
return [array objectAtIndex:row];
}
}
- 54. ViewController.m (4/4)
//設定滾輪顯⽰示的⽂文字
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
if (component==0)
{
return[keys objectAtIndex:row];
}
else
{
NSString *key = [keys objectAtIndex:
[thePickerView selectedRowInComponent:0]]; // 飲料或甜點
NSArray *array = [data objectForKey:key];
return [array objectAtIndex:row];
}
}
- 57. ViewController.m (1/2)
const int MAX_ROLL = 1000;
宣告⼀一個很⼤大的數
- (void)viewDidLoad
{ 形同有這麼多項
[super viewDidLoad];
list = [NSArray arrayWithObjects:@"AAA", @"BBB", @"CCC", @"DDD",
@"EEE", @"FFF", @"GGG", @"HHH", @"III",
@"JJJ", @"KKK", @"LLL", nil];
[self pickerViewReLoad];
}
- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:
(NSInteger)component
{
return MAX_ROLL;
}
- 58. ViewController.m (1/2)
計算相對應的元素位置
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component
{
return [list objectAtIndex:(row%[list count])];
}
-(void) pickerView:(UIPickerView *)pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component
{
[self pickerViewReLoad]; 重新移到中間但
}
相對應元素位置
-(void) pickerViewReLoad
{
NSUInteger max = MAX_ROLL;
NSUInteger base = (max/2) - (max/2)%[list count];
[myPickerView selectRow:[myPickerView
selectedRowInComponent:0]%[list count]+base
inComponent:0 animated:NO];
}
- 61. ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>
{
IBOutlet UIPickerView *pickerView;
IBOutlet UILabel *statusLabel;
NSArray *column1;
NSArray *column2;
NSArray *column3;
UIButton *spinButton;
}
@property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
@property (nonatomic, retain) IBOutlet UILabel *statusLabel;
@property (nonatomic, retain) NSArray *column1, *column2,
*column3;
- (IBAction) spin:(id)sender;
@end
- 62. ViewController.m (1/3)
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *img1 = [UIImage imageNamed:@"32_Twitter.png"];
UIImage *img2 = [UIImage imageNamed:@"32_Elephant.png"];
UIImage *img3 = [UIImage imageNamed:@"32_Babelfish.png"];
UIImage *img4 = [UIImage imageNamed:@"32_Panda.png"];
UIImage *img5 = [UIImage imageNamed:@"32_Penguin.png"];
UIImage *img6 = [UIImage imageNamed:@"32_Duckling.png"];
for (int i=1; i<=3; i++)
{
UIImageView *imgView1 = [[UIImageView alloc] initWithImage:img1];
UIImageView *imgView2 = [[UIImageView alloc] initWithImage:img2];
UIImageView *imgView3 = [[UIImageView alloc] initWithImage:img3];
UIImageView *imgView4 = [[UIImageView alloc] initWithImage:img4];
UIImageView *imgView5 = [[UIImageView alloc] initWithImage:img5];
UIImageView *imgView6 = [[UIImageView alloc] initWithImage:img6];
NSArray *array = [[NSArray alloc] initWithObjects:
imgView1, imgView2, imgView3, imgView4, imgView5, imgView6, nil];
NSString *aryName = [[NSString alloc] initWithFormat:@"column%d", i];
[self setValue:array forKey:aryName];
}
} Picker 內的資料為圖
- 63. -(IBAction) spin:(id)sender
ViewController.m (2/3)
{
BOOL win = NO;
int numInRow = 1;
int lastValue = -1;
重新指定 Picker 內指到的位置
for(int i=0; i<3; i++)
{
int newValue = arc4random() % [self.column1 count];
numInRow = (newValue==lastValue) ? (numInRow+1) : 1;
lastValue = newValue;
[pickerView selectRow:newValue inComponent:i animated:YES];
[pickerView reloadComponent:i];
if(numInRow>=2)
{
win = YES;
} "連續" 兩個相同的為贏
}
statusLabel.hidden = YES;
spinButton.hidden = YES;
if(win)
{
[self performSelector:@selector(playerWin) withObject:nil afterDelay:0.5];
}
else
{
[self performSelector:@selector(showButton) withObject:nil afterDelay:0.5];
}
statusLabel.text = @"LOSE....";
}
- 64. ViewController.m (3/3)
#pragma mark - UIPickerView Delegate
-(NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:
(NSInteger)component
{
return [self.column1 count];
}
-(UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
forComponent:(NSInteger)component reusingView:(UIView *)view
{
NSString *arrayName = [NSString stringWithFormat:@"column%d", component+1];
NSArray *array = [self valueForKey:arrayName];
return [array objectAtIndex:row];
}