幾個iOS開發的小tips
clipsToBounds vs masksToBounds
clipsToBounds
clipsToBounds 決定子檢視的顯示範圍:設定為YES時,子檢視超出部分將被剪裁,不會顯示;設定為NO則不會剪裁。 clipsToBounds的預設值為NO,但是在UIScrollview中為YES。
比如view2新增到view1上,即view2為view1的subview。
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50,150,100,100)];
view1.backgroundColor = [UIColor blueColor];
[self.view addSubview:view1];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50,50,100)];
view2.backgroundColor = [UIColor redColor];
[view1 addSubview:view2];
複製程式碼
view1的clipsToBounds設定為NO時,view2超出view1的部分將不會剪裁,如圖左,紅色部分不會被剪裁。
view1.clipsToBounds = NO;
複製程式碼
view1的clipsToBounds設定為YES時,view2超出view1的部分將會被剪裁,如圖右,紅色部分被剪掉了。
view1.clipsToBounds = YES;
複製程式碼
在Apple的Prefetching Collection View Data 示例程式碼中就是將UICollectionView 的 clipsToBounds 設定為 NO以顯示 cell 超出 UICollectionView 時的狀態,來觀察UICollectionViewCell的生命週期。
masksToBounds
masksToBounds
的功能和clipsToBounds
類似,但是clipsToBounds
是CALayer的屬性,clipsToBounds
是UIView新的屬性,clipsToBounds
會呼叫maskToBounds
方法。
通常使用在設定cornerRadius不能達到圓角效果的控制元件上,如UIImageView、UILabel等。
imageView.layer.cornerRadius = 5.f;
imageView.layer.masksToBounds = YES;
複製程式碼
需要注意,設定maskToBounds = YES
可能會觸發離屏渲染。關於可參考
UITextField && UITextView 輸入限制
限制文字輸入可以監聽UIKeyboardWillChangeFrameNotification
通知,在其中判斷文字長度。但需要注意的是:不要把高亮的部分,即聯想輸入的部分記入到字數統計中,因為這部分不是我們真正要輸入的內容。比如在中文情況下,輸入拼音時,還沒有選中文字就會被鍵盤當作字母輸入到UITextField/UITextView中,比如可輸入字元還剩下1個,此時想打一個“吃”字,輸入拼音“chi”,則會將計算的是“chi”三個字元的長度。
- (void)textViewDidChange:(UITextView *)textView {
if (textView.text.length > self.maxInputWords && !textView.markedTextRange) { // 防止把高亮的部分計入
textView.text = [textView.text substringToIndex:self.maxInputWords];
}
// 顯示已經輸入文字個數
self.wordsLabel.text = [NSString stringWithFormat:@"%lu/%ld",(long)textView.text.length,(long)self.maxInputWords];
}
複製程式碼
UITextView return鍵隱藏鍵盤
UITextView 不像 UITextfield 一樣提供了 textFieldShouldReturn:
方法實現,可以通過 UITextViewDelegate 中的textView:shouldChangeTextInRange:replacementText
代理方法實現:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:@"\n"]){ // 判斷輸入的字是否是回車,即按下 return
[textView resignFirstResponder];
return NO;
}
return YES;
}
複製程式碼
UISwitch 開關保持原來的狀態
UISwitch在點選時狀態即會改變,如果想讓它點選時不馬上改變狀態,而是進行其他操作之後再響應,可以在UISwitch的target方法中這樣操作:
[switch addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged];
- (void)switchAction:(UISwitch *)sender {
// 讓開關狀態不變
[sender setOn:!sender.on animated:YES];
// 其他操作...
// 修改開關狀態
sender.on = ...;
}
複製程式碼
注意:是把animated設定為YES。原因推測可能是animated有延時。
UITableView 單選多選實現
UITableview提供了單選和多選機制,分別是allowsSelection
和allowsMultipleSelection
屬性,但是當你想要在一個TabelView的不同section中分別使用單選和多選(比如第一個section支援單選,第二個 section 支援多選)就需要自己實現了。在 section 不多的情況下,這裡提供一種快速的方案:讓 UITableview 開啟多選,即allowsMultipleSelection=YES
,用變數記錄單選section中上一次選中的行,在tableView:didSelectRowAtIndexPath
中進行判斷,如果選擇的是不同行,則取消上一次選中。
self.tableView.allowsMultipleSelection = YES; // 允許多選
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BBASuggestFeedbackHeaderModel *headerModel;
if (indexPath.section == 0) {
// 取消上一次選中
if (self.lastSelectedIndex != indexPath.row) { // 點選同一個不做處理
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow:self.lastSelectedIndex inSection:indexPath.section];
[tableView deselectRowAtIndexPath:lastIndex animated:YES];
self.lastSelectedIndex = indexPath.row;
}
}
}
複製程式碼
獲取選中狀態的cell,即可通過indexPathsForSelectedRows
獲取。
UICollectionViewCell 高亮和點選態
UICollectionView不像UITableView一樣預設有高亮狀態,可以通過設定 UICollectionViewCell 的selectedBackgroundView實現。並且UICollectionView也提供幾個高亮的代理方法
collectionView:shouldHighlightItemAtIndexPath:
collectionView:didHighlightItemAtIndexPath:
collectionView:didUnhighlightItemAtIndexPath:
但是如果這個時候的需求是需要在高亮的時候讓cell上的其他子控制元件也改變alph值,單純的設定selectedBackgroundView的不能滿足。
可以通過重寫Cell的兩個方法setHighlighted:
和setSelected:
,
-
setHighlighted:
高亮狀態,即按在cell上不鬆開的效果 -
setSelected:
選中狀態,點選一個cell即選中
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
// 高亮狀態下的子控制元件顏色設定
} else {
// 普通狀態的子控制元件顏色設定
}
}
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
// 高亮狀態下的子控制元件顏色設定
} else {
// 普通狀態的子控制元件顏色設定
}
}
複製程式碼
Cell上UIImageView的圖片不顯示
如果cell上的UIImageView在不同情況下會size不同,圓角不同,cell複用是需要更新UIImageView的約束。遇到UIImageView中圖片不顯示的情況,可以從以下幾個方面排查:
- imageView 的 frame 是否設定正確,比如採用
initWithImage:
方法初始化時,會根據圖片的大小來設定imageView的frame可以不用初始化尺寸,但是大小不可控。 - image view 的 hidden 是否設定
- 是否新增到父 view 上
- 是否設定 imageView 的 image
- imageView 的 image 是否是從網路獲取的,是否採用佔點陣圖片
- imageView是否在設定圓角,圓角是否過大,比如ImageView的size為20 * 20,而圓角大小為40,則不會顯示。