1. 使用UIImageJPEGRepresentation(image, compressionQuality)
方法的时候内存暴涨
添加自动释放池。eg:
+ (NSData *)getCompressImageDataWithImage:(UIImage *)sourceImage {
NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];
long long size = [UIImageJPEGRepresentation(sourceImage, 1.0) length];
while (size > 1024*1024) {
//这个方法是根据大小压缩图片
sourceImage = [UIImage imageWithImageSimple:sourceImage scaledToSize:CGSizeMake(sourceImage.size.width * 0.95, sourceImage.size.height * 0.95)];
//调用UIImageJPEGRepresentation后内存就会增加好多
size = [UIImageJPEGRepresentation(sourceImage, 1.0) length];
}
NSData *sourceImageData = [UIImageJPEGRepresentation(sourceImage, 1.0) retain];
[p drain];
APPLog(@"imageData=%0.2lu k",(unsigned long) sourceImageData.length/1024);
return sourceImageData;
}
这个方法是根据源图片返回一个压缩为1M左右的图片Data。
如果是在ARC环境下,需要单独创建个文件然后添加-fno-objc-arc
。
2. 根据服务器返回的字符串数据@"\n",让控件(UILabel、UITextView)换行显示
//服务器返回的数据
NSString *string = @"我是第一行\n我是第二行";
//如果直接赋值
aLable.text = string;
//这样Label是换不了行的,显示出来就是『我是第一行\n我是第二行』
//因为服务器返回的数据里面"\n"已经是被转义过了,需要重新替换一下才能换行
string = [string stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];
//这样再赋值就会换行了
aLabel.text = string;
3. Xcode模拟器不能用Mac键盘输入了
在模拟器菜单栏选择 hardware -> keyboard ->选择第二个
如图:(还有快捷键)
4. 添加framework时选择Required | Optional
强引用(Required)的framework是一定会被加载到内存的,但是弱引用(Optional)的framework只在需要时才会被载入内存,这对于比较大的framework来说,在最初加载的时候会省很多时间。
简单解释一下,有一些库如Social.framework 和 AdSupport.framework,是在iOS6之后才被引入的,还有一些更新了新特性的只能在iOS6+上可用。当你添加一个framework到你的工程里,他们被默认强引用(Required),然而,当你最终把程序配置在运行5.0的设备上时,你会发现它通不过最户的加载,原因就在于这些库是不被iOS5.0支持的,就需要我们把这些库的引用改为Optional.
其次,如果你遇见了这个错误:
duld:Library not found………………
说明你有不应该强引用的可存在,这个错误报告里都会指明有哪些库需要弱引用。
5. View的坐标系统转换
//将调用者坐标系中的point转换成view所在坐标系的CGPoint
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
//将给定view坐标系中的point转换成调用者所在坐标系的CGPoint
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
//将调用者坐标系中的rect转换成view所在坐标系的CGRect
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
//将给定view坐标系中的rect转换成调用者所在坐标系的CGRect
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
6. tabBar和navigationBar同时存在时的title一致问题
当tabBarViewController
的一个tab
是navigationViewController
时,设置完tabbar
的每个title
,然后在navigationViewController
的rootViewController
中设置self.title = "A"
后,导致tabbar
上的title
也变成了"A"
解决办法:
self.navigationItem.title = "MedicalLibary"
或者
self.navigationController?.navigationBar.topItem?.title = "你的Title"
7. Xcode code snippet 中添加快捷替换区域
准备用swift
写项目,想添加些code snippet,但是发现忘了设置快捷替换区域是怎样的格式了,记录一下。
如图:
格式:
<#Identifier#>
显示就会如上图。
8. App中禁用第三方输入法
func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplicationExtensionPointIdentifier) -> Bool {
return false
}
9. 动画切换window的根控制器
[UIView transitionWithView:[UIApplication sharedApplication].keyWindow duration:0.5f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[UIApplication sharedApplication].keyWindow.rootViewController = [RootViewController new];
[UIView setAnimationsEnabled:oldState];
} completion:^(BOOL finished) {
}]
10. 根据传入的十六进制返回颜色值
/**
返回颜色值 根据传入的十六进制颜色值
- parameter hex: 十六进制字符串 "123456"
- returns: UIColor
*/
func getRGBColor(_ hexStr: NSString) -> UIColor {
var range : NSRange! = NSMakeRange(0, 2)
range.location = 0
range.length = 2
//r
let rString = hexStr.substring(with: range)
//g
range.location = 2;
let gString = hexStr.substring(with: range)
//b
range.location = 4;
let bString = hexStr.substring(with: range)
// Scan values
var r:CUnsignedInt = 0, g:CUnsignedInt = 0, b:CUnsignedInt = 0;
Scanner(string: rString).scanHexInt32(&r)
Scanner(string: gString).scanHexInt32(&g)
Scanner(string: bString).scanHexInt32(&b)
return UIColor(red: (CGFloat(r) / 255.0), green: (CGFloat(g) / 255.0), blue: (CGFloat(b) / 255.0), alpha: 1)
}
11. 在应用中打开设置的某个界面
// 打开设置->通用
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=General"]];
// 以下是设置其他界面
prefs:root=General&path=About
prefs:root=General&path=ACCESSIBILITY
prefs:root=AIRPLANE_MODE
prefs:root=General&path=AUTOLOCK
prefs:root=General&path=USAGE/CELLULAR_USAGE
prefs:root=Brightness
prefs:root=Bluetooth
prefs:root=General&path=DATE_AND_TIME
prefs:root=FACETIME
prefs:root=General
prefs:root=General&path=Keyboard
prefs:root=CASTLE
prefs:root=CASTLE&path=STORAGE_AND_BACKUP
prefs:root=General&path=INTERNATIONAL
prefs:root=LOCATION_SERVICES
prefs:root=ACCOUNT_SETTINGS
prefs:root=MUSIC
prefs:root=MUSIC&path=EQ
prefs:root=MUSIC&path=VolumeLimit
prefs:root=General&path=Network
prefs:root=NIKE_PLUS_IPOD
prefs:root=NOTES
prefs:root=NOTIFICATIONS_ID
prefs:root=Phone
prefs:root=Photos
prefs:root=General&path=ManagedConfigurationList
prefs:root=General&path=Reset
prefs:root=Sounds&path=Ringtone
prefs:root=Safari
prefs:root=General&path=Assistant
prefs:root=Sounds
prefs:root=General&path=SOFTWARE_UPDATE_LINK
prefs:root=STORE
prefs:root=TWITTER
prefs:root=FACEBOOK
prefs:root=General&path=USAGE prefs:root=VIDEO
prefs:root=General&path=Network/VPN
prefs:root=Wallpaper
prefs:root=WIFI
prefs:root=INTERNET_TETHERING
prefs:root=Phone&path=Blocked
prefs:root=DO_NOT_DISTURB
12. 地图上两个点之间的实际距离
// 需要导入#import
CLLocation *locA = [[CLLocation alloc] initWithLatitude:34 longitude:113];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:31.05 longitude:121.76];
// CLLocationDistance求出的单位为米
CLLocationDistance distance = [locA distanceFromLocation:locB];
13.仿苹果抖动动画
#define RADIANS(degrees) (((degrees) * M_PI) / 180.0)
- (void)startAnimate {
view.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-5));
[UIView animateWithDuration:0.25 delay:0.0 options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse) animations:^ {
view.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(5));
} completion:nil];
}
- (void)stopAnimate {
[UIView animateWithDuration:0.25 delay:0.0 options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear) animations:^ {
view.transform = CGAffineTransformIdentity;
} completion:nil];
}
14. sd设置UIButton的backgroundImage的问题
业务要求:聊天列表,用户有头像显示头像,无头像显示一个随机背景色和名字。
以下为测试代码:
//第一步
[presentButton sd_setBackgroundImageWithURL:[NSURL URLWithString:@"http://img4.duitang.com/uploads/item/201303/31/20130331124043_ZGWeU.jpeg"] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"cameraIcon"]];
//第二步
[presentButton setBackgroundImage:[UIImage imageNamed:@"select"] forState:UIControlStateNormal];
//第三步
[presentButton setTitle:@"presentButton" forState:UIControlStateNormal];
这样设置之后就会出现:既有backgroundImage又有文字"presentButton"。
原因:sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder
方法为异步下载,图片下载好了之后才会赋值给调用者,这就导致了第一步和第二步有个时间差,第二步的操作会被覆盖。
解决:在第二步之前添加代码
//Cancel the current backgroundImage download
[presentButton sd_cancelBackgroundImageLoadForState:UIControlStateNormal];
15. WebView加载带有中文的url
加载带有中文的url需要转码
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[self.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]];
16. Xcode中拖动选中的代码
1. 不需要鼠标,也不需要按压触摸板
首先请确保打开了三指滑动功能
三指滑动选中要拖动的代码,然后松开,把光标移到选中代码上,三指触摸触控板不要动,等待3秒钟再拖,就行了。
2. 需要点击鼠标左键或者按压触摸板
选中要拖动的代码,把光标移动选中代码上,按住鼠标左键或者按住触摸板不要动,等待3秒钟再拖,就行了。
17. 设置状态栏不起作用(xcode9 swift4)
在info.plist文件中,添加View controller-based status bar appearance项,添加后发现是个Bool值,字面意思:是否基于ViewController的状态条外貌。
如果设为YES,则ViewController对statusBar的设置优先级高于application的设置。
为NO则以application的设置为准,比如viewController的prefersStatusBarHidden方法无效,是根本不会被调用的。
// 设置为NO之后可以这样设置状态栏样式
UIApplication.shared.statusBarStyle = .lightContent
UIApplication.shared.statusBarStyle = .default
UIApplication.shared.isStatusBarHidden = false
UIApplication.shared.isStatusBarHidden = true
18.xib创建TableViewHeader指定高度
平常使用xib创建tableViewHeader之后,往往需要设置tableViewHeader的高度,
但有时候总是设置不准
1.把autoresizing的内部内容伸缩设置去掉,如下图
然后在代码中直接可用
//使用load加载出来之后可直接设置frame
let meTableViewHeaderView = Bundle.main.loadNibNamed(String(describing: MeTableViewHeaderView.self), owner: self, options: nil)?.first as! MeTableViewHeaderView
meTableViewHeaderView.frame = CGRect(x: 0, y: 0, width: kBYScreenWidth, height: 240)
self.tableView.tableHeaderView = meTableViewHeaderView
这样设置出来Header高度就是你指定的了。
2.不去掉autoresizing
就需要把tableViewHeader添加到一个空白的View上,设置空白View的frame,添加tableViewHeader和空白View的约束关系
19.如何找到没有使用的变量、方法、代码
https://stackoverflow.com/questions/35233564/how-to-find-unused-code-in-xcode-7
20.删除模拟器
进入到文件夹/Library/Developer/CoreSimulator/Profiles/Runtimes/
删除不需要的模拟器即可。
21.从Xib、Storybord加载控件执行方法顺序
- initWithCoder:aCoder
作用是将xib的控件通过aCoder解析器创建所有子控件,通过IBOutlet 连接的属性在这个方法里边值是null。走了initWithCoder 就不会走initWithFrame。
- awakeFormNib
是将冻结的nib控件唤醒,即所有子控件创建完毕后就会调用这个方法,在这个地方IBOutlet连接的属性才会真正的有值,所以修改nib控件的属性值应该在这个方法或者运行过程之后的方法。
22. CABasicAnimation在切换页面或者pop回来后动画停止
设置这个属性即可
rotationAnimation.removedOnCompletion = NO;