- 圓角陰影的使用導(dǎo)致界面卡頓尤其是在UICollectionView和UITableView中的使用,以下代碼大部分情況下可以馬上把你的幀數(shù)提高在55幀每秒以上聋伦,它會(huì)使視圖渲染內(nèi)容被緩存起來(lái)有序,下次繪制的時(shí)候可以直接顯示緩存报慕,當(dāng)然要在視圖內(nèi)容不改變的情況下豆巨。
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
- 同時(shí)實(shí)現(xiàn)陰影和圓角(弄一個(gè)和圖片大小一樣的view畜侦,然后把UIImageView放到里面元扔,代碼如下)
self.headImage.layer.cornerRadius = 10;
self.headImage.layer.masksToBounds = YES;
self.shadowView.layer.shadowColor = RGB(40, 45, 65).CGColor;
self.shadowView.layer.shadowOffset = CGSizeMake(1, 2);
self.shadowView.layer.shadowOpacity = 0.1;
self.shadowView.layer.shadowRadius = 4.0;
self.shadowView.layer.cornerRadius = 4.0;
self.shadowView.clipsToBounds = NO;
- 使用 plist 存儲(chǔ)的自定義對(duì)象時(shí)需要注意得時(shí)取出來(lái)的對(duì)象為不可變的,直接修改可能失敗報(bào)錯(cuò)
存儲(chǔ)自定義對(duì)象要進(jìn)行編解碼把需要存儲(chǔ)的數(shù)據(jù)轉(zhuǎn)換為NSData類(lèi)型旋膳,取出來(lái)的時(shí)候再將NSData轉(zhuǎn)換成自己的類(lèi)型 Model需要繼承NSCoding澎语,實(shí)現(xiàn)以下方法
/** 給自定義Model進(jìn)行編碼 */
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.ID forKey:@"id"];
[aCoder encodeObject:self.userCode forKey:@"userCode"];
[aCoder encodeObject:self.userName forKey:@"userName"];
[aCoder encodeObject:self.password forKey:@"password"];
[aCoder encodeObject:self.status forKey:@"status"];
[aCoder encodeObject:self.createTime forKey:@"createTime"];
[aCoder encodeObject:self.mobileNumber forKey:@"mobileNumber"];
[aCoder encodeObject:self.headImageName forKey:@"headImageName"];
[aCoder encodeBool:self.isOnWiFiDownLoad forKey:@"isOnWiFiDownLoad"];
[aCoder encodeBool:self.isAcceptInfo forKey:@"isAcceptInfo"];
}
/** 使用的時(shí)候還要進(jìn)行解碼 */
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.ID = [aDecoder decodeObjectForKey:@"id"];
self.userCode = [aDecoder decodeObjectForKey:@"userCode"];
self.userName = [aDecoder decodeObjectForKey:@"userName"];
self.password = [aDecoder decodeObjectForKey:@"password"];
self.status = [aDecoder decodeObjectForKey:@"status"];
self.createTime = [aDecoder decodeObjectForKey:@"createTime"];
self.mobileNumber = [aDecoder decodeObjectForKey:@"mobileNumber"];
self.headImageName = [aDecoder decodeObjectForKey:@"headImageName"];
self.isAcceptInfo = [aDecoder decodeBoolForKey:@"isAcceptInfo"];
self.isOnWiFiDownLoad = [aDecoder decodeBoolForKey:@"isOnWiFiDownLoad"];
}
return self;
}
如果需要修改存儲(chǔ)到plist 文件中的自定義模型的數(shù)據(jù),必須要把從plist文件中取出來(lái)的自定義對(duì)象變?yōu)榭勺儗?duì)象溺忧,這樣操作才會(huì)有效咏连,把不可變對(duì)象變?yōu)榭勺儗?duì)象 需要使Model繼承NSMutableCopying 實(shí)現(xiàn)以下方法
- (id)mutableCopyWithZone:(NSZone *)zone{
FXUserInfoModel *model = [[FXUserInfoModel allocWithZone:zone] init];
model.ID = self.ID;
model.userCode = self.userCode;
model.userName = self.userName;
model.password = self.password;
model.status =self.status;
model.createTime = self.createTime;
model.mobileNumber = self.mobileNumber;
model.headImageName = self.headImageName;
model.isAcceptInfo = self.isAcceptInfo;
model.isOnWiFiDownLoad = self.isOnWiFiDownLoad;
return model;
}
- 具體操作:
/** 從plist 中取出自定義對(duì)象*/
FXUserInfoModel *model = [[FXManager loadCustomObjectWithKey:[NSString stringWithFormat:@"%@+%@",@"FXUserInfoModel",[UserDefaultsUtils valueWithKey:@"userID"]]] mutableCopy];
/** 修改從plist中取出來(lái)的值 */
model.isOnWiFiDownLoad = NO;
/** 把修改后的值重新存回去 */
[FXManager saveCustomObject:model withKey:[NSString stringWithFormat:@"%@+%@",@"FXUserInfoModel",[UserDefaultsUtils valueWithKey:@"userID"]]];
······完美解決
- 如何實(shí)現(xiàn)互斥登陸情竹,即同一賬號(hào)只能同時(shí)在線(xiàn)一個(gè)用戶(hù)已艰,實(shí)現(xiàn)原理,服務(wù)器+友盟推送 實(shí)現(xiàn)同時(shí)只能在線(xiàn)一個(gè)賬號(hào)
- 移動(dòng)端需要我們?cè)O(shè)置HTTP請(qǐng)求頭绿饵,給請(qǐng)求頭傳入和服務(wù)器端事先約定好的參數(shù)歌溉,這里我們傳入兩個(gè)參數(shù):apiKey 垄懂,userId骑晶。第一個(gè)參數(shù)傳注冊(cè)友盟推送的時(shí)候系統(tǒng)回調(diào)傳回來(lái)的deviceToken 這個(gè)參數(shù)是為了讓后太推送確定把消息推送給指定的被下線(xiàn)的用戶(hù),第二個(gè)參數(shù)是為了確定用戶(hù)的ID登錄狀態(tài)草慧,我們還需要監(jiān)聽(tīng)收到的通知桶蛔,屆時(shí)讓服務(wù)器端配置一個(gè)自定義參數(shù)用于識(shí)別是否是下線(xiàn)通知,如果是漫谷,我們?cè)诋?dāng)前界面做出響應(yīng)仔雷,提示用戶(hù)已下線(xiàn)。2.服務(wù)器端根據(jù)請(qǐng)求頭的數(shù)據(jù)做出是否推送消息的動(dòng)作舔示,如果需要推送消息碟婆,則發(fā)送與移動(dòng)端約定好的識(shí)別參數(shù)的通知。 具體代碼如下
/** 第一步 在Application.m獲取手機(jī)注冊(cè)成功友盟推送回調(diào)得到deviceToken并保存 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *deviceTokenStr = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
[UserDefaultsUtils saveValue:deviceTokenStr forKey:@"apiKey"];
NSDictionary *parameters = [[NSMutableDictionary alloc] init];
NSString *userStr =[NSString stringWithFormat:@"%@",[UserDefaultsUtils valueWithKey:@"userID"]];
if (!userStr || [userStr isEqualToString:@""]) {
[parameters setValue:userStr forKey:@"userId"];
}else{
[parameters setValue:@"" forKey:@"userId"];
}
[parameters setValue:[UserDefaultsUtils valueWithKey:@"apiKey"] forKey:@"apiKey"];
/** 動(dòng)態(tài)設(shè)置請(qǐng)求頭必須每次調(diào)用 updateBaseUrl 方法*/
[HYBNetworking updateBaseUrl:BaseUrl];
[HYBNetworking configCommonHttpHeaders:parameters];
}
/** 在前后臺(tái)收到通知的時(shí)候判斷是否為下線(xiàn)通知惕稻,如果是提示用戶(hù)已下線(xiàn)竖共,并且退出當(dāng)前賬號(hào) */
//iOS10新增:處理前臺(tái)收到通知的代理方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//應(yīng)用處于前臺(tái)時(shí)的遠(yuǎn)程推送接受
//關(guān)閉U-Push自帶的彈出框
[UMessage setAutoAlert:NO];
//必須加這句代碼
[UMessage didReceiveRemoteNotification:userInfo];
if ([userInfo[@"operationError"] isEqualToString:@"1001"]) {
UIAlertController *alercConteoller = [UIAlertController alertControllerWithTitle:@"提示" message:@"當(dāng)前賬號(hào)已在其他設(shè)備登錄,您已被迫下線(xiàn)" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionYes = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self signOutCurrentAccount];
}];
[alercConteoller addAction:actionYes];
[[FXManager getCurrentVC] presentViewController:alercConteoller animated:YES completion:nil];
}
}else{
//應(yīng)用處于前臺(tái)時(shí)的本地推送接受
}
//當(dāng)應(yīng)用處于前臺(tái)時(shí)提示設(shè)置俺祠,需要哪個(gè)可以設(shè)置哪一個(gè)
completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}
//iOS10新增:處理后臺(tái)點(diǎn)擊通知的代理方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//應(yīng)用處于后臺(tái)時(shí)的遠(yuǎn)程推送接受
//必須加這句代碼
[UMessage didReceiveRemoteNotification:userInfo];
if ([userInfo[@"operationError"] isEqualToString:@"1001"]) {
UIAlertController *alercConteoller = [UIAlertController alertControllerWithTitle:@"提示" message:@"當(dāng)前賬號(hào)已在其他設(shè)備登錄公给,您已被迫下線(xiàn)" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionYes = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self signOutCurrentAccount];
}];
[alercConteoller addAction:actionYes];
[[FXManager getCurrentVC] presentViewController:alercConteoller animated:YES completion:nil];
}
}else{
//應(yīng)用處于后臺(tái)時(shí)的本地推送接受
}
}