iOS技巧

判断iPhoneX++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static inline BOOL isIPhoneXSeries() {
BOOL iPhoneXSeries = NO;
if (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPhone) {
return iPhoneXSeries;
}

if (@available(iOS 11.0, *)) {
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
if (mainWindow.safeAreaInsets.bottom > 0.0) {
iPhoneXSeries = YES;
}
}

return iPhoneXSeries;
}

Button 大小

1
2
3
4
5
- (CGSize)intrinsicContentSize {
CGSize originalSize = [super intrinsicContentSize];
CGSize size = CGSizeMake(originalSize.width+10, originalSize.height);
return size;
}

截屏

1
2
3
4
5
6
7
8
- (UIImage *)screenshot {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UIGraphicsBeginImageContextWithOptions(window.bounds.size, YES, [UIScreen mainScreen].scale);
[window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

设置pageControl单页不显示

1
self.pageControl.hidesForSinglePage = YES;

让数组中的所有对象都执行一下方法

1
[self.view.subViews makeObjectsPerformSelector:@selecter(removeFromSuperView)];

scrollsToTop

scrollsToTop是UIScrollView的一个属性,主要用于点击设备的状态栏时,是scrollsToTop == YES的控件滚动返回至顶部。每一个默认的UIScrollView的实例,他的scrollsToTop属性默认为YES,所以要实现某一UIScrollView的实例点击设备状态栏返回顶部,则需要关闭其他的UIScrollView的实例的scrollsToTop属性为NO。

SB跳转

1
2
3
4
5
6
7
8
9
10
// 跳转
[self performSegueWithIdentifier:@"login2Contact" sender:nil];
// 在执行跳转之前的时候调用
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

UIViewController *vc = segue.destinationViewController;
vc.title = [NSString stringWithFormat:@"%@的联系人列表", _accountField.text];
NSLog(@"%@--%@",segue.sourceViewController,segue.destinationViewController);
}

iOS 10拨打系统电话发现弹出框会延迟2s左右

解决方案一:

1
2
3
4
5
6
7
8
9
10
11
12
13
+ (void)callPhone:(NSString *)phoneNum {
if (phoneNum.length == 0) {
return;
}
NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", phoneNum];
NSComparisonResult compare = [[UIDevice currentDevice].systemVersion compare:@"10.0"];
if (compare == NSOrderedDescending || compare == NSOrderedSame) {
/// 大于等于10.0系统使用此openURL方法
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone] options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
}
}

解决方案二:

1
2
3
4
5
6
7
8
9
+ (void)callPhone:(NSString *)phoneNum {
if (phoneNum.length == 0) {
return;
}
NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", phoneNum];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
});
}

修改TableViewHeaderView字体大小

1
2
3
4
5
6
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
header.textLabel.textColor = [UIColor grayColor];
header.textLabel.font = [UIFont systemFontOfSize:15];
header.contentView.backgroundColor = [UIColor groupTableViewBackgroundColor];
}

heightForHeaderInSection设置高度无效

1
2
3
4
iOS11默认开启Self-Sizing,关闭Self-Sizing即可。
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;

屏蔽一些无知的警告

Xcode8里边 Edit Scheme-> Run -> Arguments, 在Environment Variables里边添加 OS_ACTIVITY_MODE = Disable · 如果写了之后还是打印log,请重新勾选对勾,就可以解决了。

UITableView收起键盘

1
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

长按复制功能

1
2
3
4
5
6
7
8
9
- (void)viewDidLoad {
[self.view addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pasteBoard:)]];
}
- (void)pasteBoard:(UILongPressGestureRecognizer *)longPress {
if (longPress.state == UIGestureRecognizerStateBegan) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = @"需要复制的文本";
}
}

禁止手机睡眠

1
[UIApplication sharedApplication].idleTimerDisabled = YES;

禁用button高亮

1
2
3
button.adjustsImageWhenHighlighted = NO;
或者在创建的时候
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

控制屏幕旋转,在控制器中写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** 是否支持自动转屏 */
- (BOOL)shouldAutorotate {
return YES;
}

/** 支持哪些屏幕方向 */
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

/** 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法) */
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}

获取app缓存大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (CGFloat)getCachSize {
NSUInteger imageCacheSize = [[SDImageCache sharedImageCache] getSize];
//获取自定义缓存大小
//用枚举器遍历 一个文件夹的内容
//1.获取 文件夹枚举器
NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:myCachePath];
__block NSUInteger count = 0;
//2.遍历
for (NSString *fileName in enumerator) {
NSString *path = [myCachePath stringByAppendingPathComponent:fileName];
NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
count += fileDict.fileSize;//自定义所有缓存大小
}
// 得到是字节 转化为M
CGFloat totalSize = ((CGFloat)imageCacheSize+count)/1024/1024;
return totalSize;
}

UITextView中打开或禁用复制,剪切,选择,全选等功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 继承UITextView重写这个方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
// 返回NO为禁用,YES为开启
// 粘贴
if (action == @selector(paste:)) return NO;
// 剪切
if (action == @selector(cut:)) return NO;
// 复制
if (action == @selector(copy:)) return NO;
// 选择
if (action == @selector(select:)) return NO;
// 选中全部
if (action == @selector(selectAll:)) return NO;
// 删除
if (action == @selector(delete:)) return NO;
// 分享
if (action == @selector(share)) return NO;
return [super canPerformAction:action withSender:sender];
}

禁止textField和textView的复制粘贴菜单

1
2
3
4
5
6
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if ([UIMenuController sharedMenuController]) {
[UIMenuController sharedMenuController].menuVisible = NO;
}
return NO;
}

为一个view添加虚线边框

1
2
3
4
5
6
7
 CAShapeLayer *border = [CAShapeLayer layer];
border.strokeColor = [UIColor colorWithRed:67/255.0f green:37/255.0f blue:83/255.0f alpha:1].CGColor;
border.fillColor = nil;
border.lineDashPattern = @[@4, @2];
border.path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
border.frame = view.bounds;
[view.layer addSublayer:border];

设置tableView分割线颜色

1
[self.tableView setSeparatorColor:[UIColor myColor]];

UIImage和base64互转

1
2
3
4
5
6
7
8
- (NSString *)encodeToBase64String:(UIImage *)image {
return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}

- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [UIImage imageWithData:data];
}

摇一摇功能

1
2
3
4
5
6
7
8
9
10
11
1、打开摇一摇功能
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
2、让需要摇动的控制器成为第一响应者
[self becomeFirstResponder];
3、实现以下方法
// 开始摇动
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
// 取消摇动
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
// 摇动结束
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event

发起QQ聊天

QQ开通推广服务以接收陌生消息

1
2
3
4
5
6
7
8
//是否安装QQ
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]) {
//用来接收临时消息的客服QQ号码(注意此QQ号需开通QQ推广功能,否则陌生人向他发送消息会失败)         
NSString *QQ = @"1099779883";         
//调用QQ客户端,发起QQ临时会话         
NSString *url = [NSString stringWithFormat:@"mqq://im/chat?chat_type=wpa&uin=%@&version=1&src_type=web",QQ];         
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
}

MJRefresh

webview去掉长按后的选择和复制菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. webview 执行 js
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {

NSLog(@"%s", __FUNCTION__);
// 禁用选中效果
[self.webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
[self.webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];

}

func webViewDidFinishLoad(webView: UIWebView) {
//禁用webview长按后文字选择框和放大框
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")
}

2. 或者前端写css
<style type="text/css">
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>

XIB 可见属性设置(eg: 圆角)

  1. OC: IB_DESIGNABLEIBInspectable

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // .h
    @property (nonatomic, assign) IBInspectable CGFloat cornerRadius;

    // .m
    IB_DESIGNABLE @implementation KLButton
    - (void)setCornerRadius:(CGFloat)cornerRadius {
    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = (cornerRadius > 0);
    }

    - (CGFloat)cornerRadius {
    return self.layer.cornerRadius;
    }
  2. Swift: IBInspectableIBDesignable

方法不确定的参数 va_arg 宏的使用

当我们方法需要传入多个不确定的参数时(如:[NSArray arrayWithObjects]), 我们可以使用 ,… 的形式表示,当要取传入的参数的值时就需要用到 va_arg 宏去取。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (void)viewDidLoad {
[super viewDidLoad];
[self testMethod:@"123",@"456",@"789",nil];
}


- (void)testMethod:(NSString *)test,.. NS_REQUIRES_NIL_TERMINATION {
va_list argList;
va_start(argList, test);
{
for (id params = test; params != nil; params = va_arg(argList, id)){

NSLog(@"id = %@---class = %@",params,NSStringFromClass([params class]));
}
}
va_end(argList);
}

去除数组中重复的对象

1
NSArray *newArr = [oldArr valueForKeyPath:@"@distinctUnionOfObjects.self"];

删除NSUserDefaults所有记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//方法一
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
//方法二
- (void)resetDefaults {
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary * dict = [defs dictionaryRepresentation];
for (id key in dict) {
[defs removeObjectForKey:key];
}
[defs synchronize];
}
// 方法三
[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];

UITableViewCell 分割线置顶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 10, 0, 0)];
}

if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsMake(0, 10, 0, 0)];
}
// 3. cell 下
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}

设置UIViewController的view的top在navigationBar下面 & bottom位置在Tabbar的上面

1
2
tabBarController.tabBar.translucent = NO;
uiviewController.navigationController.navigationBar.translucent = NO;

禁用button高亮,点击变灰的效果

1
2
3
button.adjustsImageWhenHighlighted = NO;
或者在创建的时候
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

自定义cell选中背景颜色

1
2
3
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor redColor];
[cell setSelectedBackgroundView:bgColorView];

UILabel设置内边距

1
2
3
4
5
6
子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect {
// 边距,上左下右
UIEdgeInsets insets = {0, 5, 0, 5};
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

UILabel设置文字描边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
// 设置描边宽度
CGContextSetLineWidth(c, 1);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextStroke);
// 描边颜色
self.textColor = [UIColor redColor];
[super drawTextInRect:rect];
// 文本颜色
self.textColor = [UIColor yellowColor];
CGContextSetTextDrawingMode(c, kCGTextFill);
[super drawTextInRect:rect];
}

改变UISlider的进度条高度

需要继承UISlider并t重载trackRectForBounds方法

1
2
3
- (CGRect)trackRectForBounds:(CGRect)bounds {
return CGRectMake(0, 0, CGRectGetWidth(self.frame), 5.0);
}

iOS 11中隐藏section头尾的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0.1f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.1f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return nil;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return nil;
}

更改UITabBar && UINavigationBar背景颜色

1
2
[[UITabBar appearance] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];

更改UITabBar && UINavigationBar字体颜色

1
2
3
4
5
6
7
//改变按钮navigationBar tintColor颜色
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:102/255.0 green:102/255.0 blue:102/255.0 alpha:1.0];
//改变tabbar 正常颜色,选中色
NSDictionary *attributeNormal = @{NSForegroundColorAttributeName:[UIColor grayColor]};
[subVC.tabBarItem setTitleTextAttributes:attributeNormal forState:(UIControlStateNormal)];
NSDictionary *attributeSelected = @{NSForegroundColorAttributeName:[UIColor redColor]};
[subVC.tabBarItem setTitleTextAttributes:attributeSelected forState: (UIControlStateSelected)];


-------------The End-------------

本文标题:iOS技巧

文章作者:kysonyangs

发布时间:2015年10月06日 - 20:10

最后更新:2018年11月05日 - 15:11

原始链接:https://kysonyangs.github.io/default/iOS技巧/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。