Swift / Objective_C / Xcode实际开发中可能遇到的小功能小技巧总结
Posted Stevin的技术博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift / Objective_C / Xcode实际开发中可能遇到的小功能小技巧总结相关的知识,希望对你有一定的参考价值。
一:Swift3.0为视图添加旋转动画,效果如下:
代码实现:
//创建动画
let anim = CABasicAnimation(keyPath: "transform.rotation")
//设置相关属性
anim.toValue = 2 * M_PI
anim.repeatCount = MAXFLOAT
anim.duration = 15
//完成之后不移除,testView被释放,动画随着一起删除
anim.isRemovedOnCompletion = false
testView(anim, forKey: nil)
二:解决项目中每次界面跳转隐藏TabBar的问题
思路:在UINavigationController
中重写pushViewController
方法,不必每次跳转都调用hidesBottomBarWhenPushed
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
//隐藏tabbar
if childViewControllers.count > 0 {
viewController.hidesBottomBarWhenPushed = true
}
super.pushViewController(viewController, animated: animated)
}
三:Swift3.0中使用NSLayoutConstraint
为控件添加约束
//设置通过代码添加Constraint,否则View还是会按照以往的autoresizingMask进行计算
centerButton.translatesAutoresizingMaskIntoConstraints = false
//依次添加X,Y, W,H
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1.0, constant: 0))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1.0, constant: -60))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50))
方法解读:
在view视图中,为参数1
添加约束
设置 参数1(一般为视图)
的 参数2(坐标或宽高)
属性 参数3(大于等于小鱼)
参数4(参照视图)
的 参数5(坐标或宽高)
属性 乘以 参数6
加上 参数7
注意:单纯设置宽高的时候,参数4传入nil
,参数5传入.notAnAttribute
view.addConstraint(NSLayoutConstraint(item: 参数1, attribute: 参数2, relatedBy: 参数3, toItem: 参数4, attribute: 参数5, multiplier: 参数6, constant: 参数7))
四:Swift3.0通过十六进制值设置UIColor
extension UIColor {
class func colorWithHex(hexValue: UInt32) -> UIColor {
let r = (hexValue & 0xff0000) >> 16
let g = (hexValue & 0x00ff00) >> 8
let b = hexValue & 0x0000ff
return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: 1.0)
}
}
//示例调用:
view.backGroundColor = UIColor.colorWithHex(hexValue: 0xff0000)
五:Swift3.0中&error
的写法
var error: NSError?
context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error)
六:动态设置TableView
的滑动范围
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//一般获取最后控件的最大Y坐标,labelExplain是最后一个cell下追加的控件
self.tableView.contentSize = CGSizeMake(0,CGRectGetMaxY(self.labelExplain.frame) + 10);
}
七:clipstobounds与maskstobounds的区别
clipsToBounds(UIView)
是指视图上的子视图,如果超出父视图的部分就截取掉
masksToBounds(CALayer)
却是指视图的图层上的子图层,如果超出父图层的部分就截取掉
八:查看真机沙盒文件夹,查看真机崩溃日志
九:常用的路径位置
模拟器的位置:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs
文档安装位置:
/Applications/Xcode.app/Contents/Developer/Documentation/DocSets
插件保存路径:
~/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins
自定义代码段的保存路径:
~/Library/Developer/Xcode/UserData/CodeSnippets/ //如果找不到CodeSnippets文件夹,可以自己新建一个CodeSnippets文件夹。
描述文件路径
~/Library/MobileDevice/Provisioning Profiles
十:富文本和HTML字符串互相转化
//富文本转html字符串
- (NSString *)attriToStrWithAttributeString:(NSAttributedString *)attributeString
{
NSDictionary *tempDic = @{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute:[NSNumber numberWithInt:NSUTF8StringEncoding]};
NSData *htmlData = [attributeString dataFromRange:NSMakeRange(0, attributeString.length) documentAttributes:tempDic error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}
//html字符串转富文本
- (NSAttributedString *)strToAttriWithString:(NSString *)htmlString
{
return [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
}
十一:Swift项目中引入Objective_C三方框架后手动桥接的方法
1>手动创建一个.h
的文件,比如:Demo-Bridge.h
2>在Build Setteings
中找到 Objective_C Bridging Header
添加路径$(SRCROOT)/Demo/Demo-Bridge.h
3>包含Objective_C
头文件,例如:#import "UIView+WebCache.h"
十二:UITableView多行选择修改系统默认选择样式
在自定义的cell中重写layoutSubviews
- (void)layoutSubviews
{
[super layoutSubviews];
// 设置UITableViewCellEditControl样式
for (UIControl *control in self.subviews) {
if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]) {
for(UIView *view in control.subviews) {
if([view isKindOfClass: [UIImageView class]]) {
UIImageView *img = (UIImageView *)view;
if(self.selected) {
//选择状态图片
img.image= [UIImage imageNamed:@"image1"];
} else {
//未选中状态图片
img.image= [UIImage imageNamed:@"image2"];
}
}
}
}
}
}
十三:Xcode项目中一键替换项目中所有类中指定文字或代码
1>快捷键command + shift + F
唤醒全局搜索并进入输入状态
2>切换Find
为Replace
(这里也可以采用正则进行查找搜索Regular Expression
)
3>输入要搜索的内容和替换结果,然后点击Replace All
即可
十四:NSUserDefaults
判断应用程序是否是安装完首次次启动
if (![[NSUserDefaults standardUserDefaults] valueForKey:@"FirstStart"]) {
[[NSUserDefaults standardUserDefaults] setValue:@"firstStart" forKey:@"FirstStart"];
//第一次启动,可以设置欢迎页或者设置默认语言
} else {
//非第一次启动
}
十五:Swift 设置在debug模式下打印日志,并且锁定代码位置(Objective_C打印设置)
// 可以把下列代码放在AppDelegate的@UIApplicationMain的上方
func DebugLog<T>(messsage : T, file : String = #file, funcName : String = #function, lineNum : Int = #line) {
#if DEBUG
let fileName = (file as NSString).lastPathComponent
print("\\(fileName):(\\(lineNum))-\\(messsage)")
#endif
}
//使用方法
DebugLog(messsage: "test")
//输出类名 + 代码行数 + 输出信息
ViewController.swift:(37)-test
十六:修改默认开发语言(Xcode默认开发语言是英语)
1>先添加英语之外的一种语言
2>Show in Finder
工程文件 –> 显示包内容 –> 用文本打开project.pbxproj
–> 搜索developmentRegion
–> 将值改为zh-Hans
3>修改成功
十七:使用runtime
为分类添加属性
我们知道系统的UITableView
的section
和row
属性,就是定义在NSIndexPath
的分类里的
示例方法:
//写一个UIView的分类命名:UIView+Category
UIView+Category.h
//增加的属性
@property (nonatomic, strong) NSObject *propertyTest;
UIView+Category.m
//加入运行时头文件
#import <objc/runtime.h>
@implementation UIView (Category)
//获取关联的对象
- (NSObject *)propertyTest {
return objc_getAssociatedObject(self, @selector(propertyTest));
}
//给对象添加关联对象
- (void)setPropertyTest:(NSObject *)value {
objc_setAssociatedObject(self, @selector(propertyTest), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
此后,就可以正常访问了该属性了
十八:App迭代开发版本号的规则
0>首先我们的App第一版本首次上线, 比如以1.0.0为首次上线的版本号
1>上线后突然发现一个严重的Bug那我们就要修复更新版本, 此时我们的版本号为1.0.1, 所以说如果修复Bug或者优化功能, 我们只修改叠加第三位数字, 其他不变
2>如果有了新的需求, 在原来的基础上增加了一个新功能, 那么我们的版本号变为1.1.0, 需要清空第三位数字为0, 来叠加修改第二位数字
3>如果App需求功能大改, 更新量非常大, 那我们的版本号变为2.0.0, 需要叠加修改第一位数字, 清空其他数字为0
十九:Swift中懒加载
先说说OC
中的懒加载,通常是写get
方法,例如:
- (DataModel *)model
{
if (!_model) {
_model = [[DataModel alloc] init];
_model.title = @"标题";
}
return _model;
}
swift
中有专门的懒加载修饰符lazy
,实现如下:
private lazy var model: DataModel = {
let model = DataModel()
model.title = "标题"
return model
}()
二十:Swift中shouldAutorotate
的重写
override open var shouldAutorotate: Bool {
return false / true
}
//或者
open override var shouldAutorotate: Bool {
get {
return false / true
}
}
二十一:屏幕旋转的时候状态栏显示问题
如果是在视图View
中,重写layoutSubviews
;如果是在ViewController
中重写viewWillLayoutSubviews
,Swift
代码如下:
//视图控制器中
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
UIApplication.shared.isStatusBarHidden = false
}
//视图中
override func layoutSubviews() {
super.layoutSubviews()
UIApplication.shared.isStatusBarHidden = false
}
二十二:区分==
,isEqual
,isEqualToString
==
: 比较的是内存地址
isEqual
: 是 NSObject
的方法,首先都会判断指针是否相等 ,相等直接返回YES
,不相等再判断是否是同类对象或非空,空或非同类对象直接返回NO
,而后依次判断对象对应的属性是否相等,若均相等,返回YES
isEqualToString
: 是NSString
的方法,从继承关系角度来说是 isEqual
的衍生方法,在都是字符串的前提下,判断字符串的内容是否相等,如果知道了两个对象都是字符串,isEqualToString
比isEqual
要快
二十三:修改GitHub
项目显示语言
打开Terminal 进入到仓库文件夹
$:cd /Users/MacName/Desktop/Demo
创建一个`.gitattributes`的文件
$:touch .gitattributes
打开文件
$:open .gitattributes
写入如下代码,比如设置语言为Swift
*.h linguist-language=swift
*.m linguist-language=swift
重新push项目到GitHub, 完成修改
二十四:Terminal命令查看系统隐藏文件
显示隐藏文件:
$:defaults write com.apple.finder AppleShowAllFiles -bool true
关闭显示隐藏文件:
defaults write com.apple.finder AppleShowAllFiles -bool false
***执行命令后需要打开强制退出界面(快捷键option+command+esc),重启Finder
二十五:Masonry
布局后获取Frame
值
需要立即更新子视图的布局后获取即可
[self layoutIfNeeded];
二十六:Xcode
同时打开两个Simulator
模拟器(做通信APP
方便调试)
打开终端进到xcode路径下的Applications路径
$:cd /Applications/Xcode.app/Contents/Developer/Applications/
打开模拟器
$:open -n Simulator.app/
或者执行一个脚本也可以,创建文件xim.sh
,键入以下代码
#!/bin/sh
cd /Applications/Xcode.app/Contents/Developer/Applications/
open -n Simulator.app/
sudo sh sim.sh
会有如下提示:
点击OK
后,换一个与当前模拟器设备不同的机型
然后在Xcode
中选择刚选取的机型run
包即可同时打开调试
实际上多开别的APP
道理也是一样的,进到APP
应用目录,open -n appName.app/
即可
二十七:TableView
检测滑动到底部和顶部(可用于聊天界面取历史消息)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.frame.size.height) {
NSLog(@"滑到底部加载更多");
}
if (scrollView.contentOffset.y == 0) {
NSLog(@"滑到顶部更新");
}
}
// 另外点击状态栏会调用
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
NSLog(@"点击状态栏调用");
}
二十八:区分__weak
,__unsafe_unretained
,__block
__weak 在释放指针后能够同时将指针置为nil
__unsafe_unretained 只留下一个无效的也指针
__block 打破循环 copy副本 内部修改
二十九:Xcode恢复默认字体
三十:UIAlertView点击背景消失的方法
- (void)longPressTableViewShowAlertView:(UIGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan) {
self.alertView = [[UIAlertView alloc] initWithTitle:@"请输入审批意见" message:nil delegate:self cancelButtonTitle:@"同意" otherButtonTitles:@"驳回", nil];
[self.alertView setAlertViewStyle:UIAlertViewStylePlainTextInput];
self.alertView.delegate = self;
[self.alertView show];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
tap.numberOfTapsRequired = 1;
tap.cancelsTouchesInView = NO;
[[UIApplication sharedApplication].keyWindow addGestureRecognizer:tap];
}
}
- (void)tap:(UITapGestureRecognizer *)tap
{
if (tap.state == UIGestureRecognizerStateEnded){
CGPoint location = [tap locationInView:nil];
if (![self.alertView pointInside:[self.alertView convertPoint:location fromView:self.alertView.window] withEvent:nil]){
[self.alertView.window removeGestureRecognizer:tap];
[self.alertView dismissWithClickedButtonIndex:0 animated:YES];
}
}
}
以上是关于Swift / Objective_C / Xcode实际开发中可能遇到的小功能小技巧总结的主要内容,如果未能解决你的问题,请参考以下文章
UINavigationBar.appearance().tintColor 在 Swift 中不起作用
调试 Xamarin C# iOS 应用程序时抛出 Objective_C 异常
iOS面试题---Objective_C语言特性:分类扩展代理通知KVOKVC属性