看網(wǎng)上有人整理 iOS 開發(fā)中常用的易忘知識(shí)點(diǎn)的畴,iOS 開發(fā)小冷易忘知識(shí)點(diǎn)總結(jié)塘砸,覺得不錯(cuò)末融,于是自己也想著整理一些易忘的知識(shí)點(diǎn)。會(huì)持續(xù)更新......
- iOS 控制器的基類暇韧,搭建框架之初一般都會(huì)設(shè)計(jì)一個(gè) ViewController 基類勾习,這里設(shè)置的基類是 NNBaseViewController,繼承自 UIViewController懈玻。
#import "NNBaseViewController.h"
@interface NNBaseViewController ()
@end
@implementation NNBaseViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViews];
// 判斷是否有上級(jí)頁(yè)面巧婶,有的話再設(shè)置返回按鈕
if ([self.navigationController.viewControllers indexOfObject:self] != 0) {
[self setupLeftBarButton];
}
}
- (void)setupViews {
// 設(shè)置應(yīng)用的背景色
self.view.backgroundColor = [UIColor lightGrayColor];
// 不允許 viewController 自動(dòng)調(diào)整,我們自己布局酪刀;如果設(shè)置為YES粹舵,視圖會(huì)自動(dòng)下移 64 像素
self.automaticallyAdjustsScrollViewInsets = NO;
}
#pragma mark - 自定義返回按鈕
- (void)setupLeftBarButton {
// 自定義 leftBarButtonItem ,UIImageRenderingModeAlwaysOriginal 防止圖片被渲染
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithImage:[[UIImage imageNamed:@"Back-藍(lán)"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
style:UIBarButtonItemStylePlain
target:self
action:@selector(leftBarButtonClick)];
// 防止返回手勢(shì)失效
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
}
- (void)leftBarButtonClick {
[self.navigationController popViewControllerAnimated:YES];
}
@end
- 隱藏 navigationControll 左側(cè)的返回按鈕
因?yàn)轫?xiàng)目需要骂倘,有時(shí)需要隱藏 navigationControll 左側(cè)或右側(cè)的按鈕眼滤。
// 這兩句貌似不太管用
self.navigationItem.leftBarButtonItems = nil;
self.navigationItem.rightBarButtonItem = nil;
// 可以試試這兩句代碼
self.navigationItem.hidesBackButton = YES;
self.navigationItem.rightBarButtonItem.customView.hidden = YES;
- 改變 button 內(nèi)部的圖片以及文字的偏移量
有時(shí)候需要在 button 的右部添加指示箭頭,但 button 默認(rèn)的是圖片在左历涝,文字在右诅需,因此想要實(shí)現(xiàn)項(xiàng)目需求,我們需要改變 button 內(nèi)部的偏移量荧库。在 storyboard 或 xib 中也可以改變 button 內(nèi)部的圖片以及文字的偏移量堰塌,但貌似沒有做適配的地方,那么在不同機(jī)型上的顯示就會(huì)有問題(如果哪位道友發(fā)現(xiàn)可以在 storyboard 或 xib 中可以做適配分衫,還請(qǐng)告知)场刑,下面是改變 button 內(nèi)部圖片以及文字偏移量的代碼。
// 已經(jīng)做了適配蚪战,各位可以根據(jù)需要做屏幕適配
self.changeSpecialistBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -lengthFit(16), 0, 0);
self.changeSpecialistBtn.imageEdgeInsets = UIEdgeInsetsMake(0, lengthFit(76), 0, 0);
- tableView 滾動(dòng)時(shí)自動(dòng)收起鍵盤
項(xiàng)目中某個(gè) tableView 頁(yè)面有文字搜索功能牵现,輸入文本完畢之后滾動(dòng) tableView,要求鍵盤自動(dòng)收起邀桑。
self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
- 判斷上級(jí)頁(yè)面是哪個(gè)頁(yè)面
// 我這里的項(xiàng)目需求是瞎疼,如果上一個(gè)頁(yè)面是 KXOrderCenterViewController,就隱藏稍后支付按鈕壁畸,否則不隱藏
NSArray *array = self.navigationController.viewControllers;
if ([array[0] isKindOfClass:[KXOrderCenterViewController class]]) {
self.payLaterBtn.hidden = YES;
} else {
self.payLaterBtn.hidden = NO;
}
- 從任意界面返回 NavigationController 中的任意一個(gè)
這個(gè)方法還是挺實(shí)用的贼急,從某個(gè)界面跳轉(zhuǎn)到任意一個(gè)界面。
// 得到當(dāng)前的 NavigationController
[[APPDELEGATE getCurrentViewController].navigationController popToRootViewControllerAnimated:NO];
// 跳轉(zhuǎn)到哪個(gè) NavigationController捏萍,這里下標(biāo)為1太抓,表示第二個(gè)
[APPDELEGATE.tabBarController setSelectedIndex:1];
// 退出當(dāng)前界面并執(zhí)行 block 中的內(nèi)容
[self.navigationController dismissViewControllerAnimated:YES completion:^{
UINavigationController *navi = APPDELEGATE.tabBarController.viewControllers[1];
// 保險(xiǎn)起見,再判斷下是否是將要跳轉(zhuǎn)到的頁(yè)面
if ([navi.viewControllers[0] isKindOfClass:[KXOrderCenterViewController class]]) {
// 我這里需要刷新
KXOrderCenterViewController *orderCenter = navi.viewControllers[0];
[orderCenter beginRefreshing];
}
}];
- 設(shè)置導(dǎo)航欄右部點(diǎn)擊按鈕令杈,并添加點(diǎn)擊事件
// 添加文字按鈕
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithTitle:@"編輯" style:UIBarButtonItemStylePlain target:self action:@selector(editor)];
self.navigationItem.rightBarButtonItem = rightBarButton;
// 添加圖片按鈕
UIBarButtonItem *rightBarBtn = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"圖片名"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(rightBarButtonEvent)];
[self.navigationItem setRightBarButtonItem:rightBarBtn];
- 給 view 添加手勢(shì)腻异,并加入點(diǎn)擊事件
UITapGestureRecognizer *operationTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(gotoCapture:)];
[self.operationView addGestureRecognizer:operationTap];
- textview 輸入文本,服務(wù)器那邊要求返回文本個(gè)數(shù)不超過32
服務(wù)器那邊有限制这揣,要求返回文本個(gè)數(shù)不超過32個(gè)悔常。影斑。。于是這里做了判斷机打,如果超過32個(gè)就不再允許輸入矫户,允許刪除。
- (void)textViewDidChange:(UITextView *)textView {
[self updateViewHeight];
// 該判斷用于聯(lián)想輸入
if (textView == self.secondDiagnosisTextView) {
if (textView.text.length > 32) {
// 截取字符串
textView.text = [textView.text substringToIndex:32];
// HUD 提示
[CommunityPublicClass showHUDwithLabelText:@"最多輸入32個(gè)字" andDetailsLabelText:nil];
}
}
}
// 代理方法規(guī)定只能輸入32個(gè)字
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
// 輸入32字之后残邀,允許刪除
if ([text isEqualToString:@""]) {
return YES;
}
if (textView == self.secondDiagnosisTextView) {
if (textView.text.length == 0)
return YES;
NSInteger existedLength = textView.text.length;
NSInteger selectedLength = range.length;
NSInteger replaceLength = text.length;
if (existedLength - selectedLength + replaceLength > 32) {
// HUD 提示
[CommunityPublicClass showHUDwithLabelText:@"最多輸入32個(gè)字" andDetailsLabelText:nil];
return NO;
}
}
return YES;
}
- textfield 中輸入手機(jī)號(hào)皆辽,只允許輸入數(shù)字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (textField == self.secondAgeTextField) {
if ([self isPureInt:string] || [string isEqualToString:@""]) {
return YES;
}else{
return NO;
}
}
return YES;
}
// 判斷輸入的是否是純數(shù)字
- (BOOL)isPureInt:(NSString*)string{
NSScanner *scan = [NSScanner scannerWithString:string];
int val;
return [scan scanInt:&val] && [scan isAtEnd];
}
- 給 button 設(shè)置邊框、圓角芥挣、邊框設(shè)置顏色
[self.completeBtn.layer setBorderWidth:1.0];
self.completeBtn.layer.cornerRadius = 1;
[self.completeBtn.layer setBorderColor:KXColorTextBlack.CGColor];
- 設(shè)置圖片拉伸
有時(shí) UI 設(shè)計(jì)師給出的圖片并不合適驱闷,比如我們這的 UI 設(shè)計(jì)師一邊忙 web 端,一邊忙我們移動(dòng)端空免,有時(shí)候都不忍心讓他重新作圖空另,于是只好自己想辦法
// 設(shè)置圖片拉伸
UIImage *bgImage = [UIImage imageNamed:@""];
_bgImageView.image = [bgImage stretchableImageWithLeftCapWidth:15 topCapHeight:15];
- 點(diǎn)擊單元格時(shí),默認(rèn)的點(diǎn)擊效果比較丑蹋砚,大多時(shí)候不顯示點(diǎn)擊效果
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES] ;
}
- 改變導(dǎo)航欄標(biāo)題的顏色
UIColor *color = [UIColor cyanColor];
NSDictionary *dictionary = [NSDictionary dictionaryWithObject: color forKey:NSForegroundColorAttributeName];
self.navigationController.navigationBar.titleTextAttributes = dictionary;
- 延遲調(diào)用
// 延遲兩秒鐘調(diào)用 beginAction 方法
[self performSelector:@selector(beginAction) withObject:nil afterDelay:0.2] ;
- 項(xiàng)目中用到了 UISwitch 控件扼菠,需要更改它的大小
// 改變 UISwitch 的大小,CGAffineTransformMakeScale(CGFloat x, CGFloat y) 對(duì) view 的長(zhǎng)和寬進(jìn)行縮放坝咐,不改變 view 的中心點(diǎn)
self.orderSwitch.transform = CGAffineTransformMakeScale(0.7, 0.7);
// 改變 UISwitch 開啟時(shí)的顏色
self.orderSwitch.onTintColor = KXColorBlue;
- 在做明暗文切換(密碼輸入框)的時(shí)候遇見一個(gè)坑——就是切換 secureTextEntry 的時(shí)候循榆,輸入框的光標(biāo)會(huì)偏移,下面是解決辦法及明暗文切換的方法:
- (IBAction)btnClick:(UIButton *)sender {
sender.selected = !sender.selected;
NSString *passwordString = self.passwordText.text;
// 這句代碼可以防止切換的時(shí)候光標(biāo)偏移
self.passwordText.text = @"";
if (sender.selected) { // 明文
self.passwordText.secureTextEntry = NO;
} else { // 暗文
self.passwordText.secureTextEntry = YES;
}
self.passwordText.text = passwordString;
}
- 判斷屏幕橫屏/豎屏(在ViewController里面)
// 屏幕發(fā)生翻轉(zhuǎn)的時(shí)候會(huì)調(diào)用
- (void)viewWillLayoutSubviews {
[self shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];
}
- (void)shouldRotateToOrientation:(UIDeviceOrientation)orientation {
if (orientation == UIDeviceOrientationPortrait ||orientation == UIDeviceOrientationPortraitUpsideDown) {
NSLog(@"這是豎屏");
} else {
NSLog(@"這是橫屏");
}
}
- 加載本地的 HTML 文件墨坚,比如文件名字是
serviceDescription.html
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *filePath = [resourcePath stringByAppendingPathComponent:@"serviceDescription.html"];
NSString *htmlString = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString: htmlString baseURL: [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
- iOS 項(xiàng)目開發(fā)中用的一部分宏定義
/** self的弱引用 */
#define NNWeakSelf __weak typeof(self) weakSelf = self;
/** self的強(qiáng)引用 */
#define NNStrongSelf __strong __typeof(weakSelf)strongSelf = weakSelf;
#define NNColorBlue [UIColor colorWithRed:0.0/255.0f green:135.0/255.0f blue:209.0/255.0f alpha:1]
#define NNFontBoldText [UIFont boldSystemFontOfSize:fontFit(16)]
#define NNFontText [UIFont systemFontOfSize:fontFit(16)]
#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height
#define iPhone5 (([[UIScreen mainScreen] bounds].size.height*[[UIScreen mainScreen] bounds].size.width <= 320*568)?YES:NO)
#define iPhone6 (([[UIScreen mainScreen] bounds].size.height*[[UIScreen mainScreen] bounds].size.width <= 375*667)?YES:NO)
#define iPhone6p (([[UIScreen mainScreen] bounds].size.height*[[UIScreen mainScreen] bounds].size.width <= 414*736)?YES:NO)
#define iOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 ? YES : NO) // 是否IOS7
static inline float lengthFit(float iphone6PlusLength)
{
if (iPhone5) {
return iphone6PlusLength *320.0f/414.0f;
}
if (iPhone6) {
return iphone6PlusLength *375.0f/414.0f;
}
return iphone6PlusLength;
}
static inline float fontFit(float iphone6PlusFont)
{
if (iPhone5) {
return iphone6PlusFont - 2;
}
if (iPhone6) {
return iphone6PlusFont - 1;
}
return iphone6PlusFont;
}
#define PlaceholderAvatarImage [UIImage imageNamed:@"默認(rèn)頭像"]
- 一句代碼隱藏 UITableView 中空的 cell
self.tableView.tableFooterView = [[UIView alloc] init];
- 自定義 leftBarButtonItem 返回按鈕時(shí)秧饮,防止返回手勢(shì)失效的辦法
- (void)setupLeftBarButton {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithImage:[[UIImage imageNamed:@"Back-藍(lán)"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
style:UIBarButtonItemStylePlain
target:self
action:@selector(leftBarButtonClick)];
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
}
- (void)leftBarButtonClick {
[self.navigationController popViewControllerAnimated:YES];
}
- 不允許 viewController 自動(dòng)調(diào)整,我們自己布局泽篮;如果設(shè)置為YES盗尸,視圖會(huì)自動(dòng)下移 64 像素
self.automaticallyAdjustsScrollViewInsets = NO;
- 去空格,開發(fā)中有些地方不需要空格咪辱,這里記錄一下
// 去掉兩端的空格
[trimString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// 去掉所有空格
[trimString stringByReplacingOccurrencesOfString:@" " withString:@""];
- 判斷字符串中是否包含非法字符
if ([self.searchText.text rangeOfString:@"'"].location != NSNotFound) {
// 用封裝好的提示框提示
[CommunityPublicClass showHUDwithLabelText:@"您輸入的字符不合法" andDetailsLabelText:nil];
return;
}
- iOS 導(dǎo)航欄的正確隱藏方法
第一種方法
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
第二種方法
@interface NNViewController () <UINavigationControllerDelegate>
@end
@implementation NNViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 設(shè)置導(dǎo)航控制器的代理為self
self.navigationController.delegate = self;
}
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[self.navigationController setNavigationBarHidden: [viewController isKindOfClass:[self class]] animated:YES];
}
- 判斷字符串是否為空
// 判斷字符串是否為空
+ (BOOL)isBlankString:(NSString *)string {
if (string == nil || string == NULL) {
return YES;
}
if ([string isKindOfClass:[NSNull class]]) {
return YES;
}
if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
return YES;
}
return NO;
}
- 把一個(gè) view 的所有subview清空
[view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];