iOS - 开发
程序员文章站
2022-03-23 20:34:32
1. Xcode在真机调试的时候出现”The identity used to sign the executable is no longer valid&rdquo...
1. Xcode在真机调试的时候出现”The identity used to sign the executable is no longer valid”
解决方案:
(1)provisioning Profile文件选择错误
(2)provisioning Profile已失效
(3)开发者证书过期或者被删除了
2. 将storyBoard里的控制器进行实例化
注:需要在Storyboard里面设置控制器的Storyboard ID
//Identifier:@“Storyboard ID” //将storyBoard实例化 (1)(可以在AppDelegate里面使用) UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //将要跳转控制器通过storyBoard实例化 ViewController *VC = [mainSB instantiateViewControllerWithIdentifier:@"ViewController"]; VC.isModifyPassword = NO; [self.navigationController pushViewController:VC animated:YES]; //将storyBoard实例化 (2) //将要跳转控制器通过storyBoard实例化 ViewController *VC = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController"]; VC.isModifyPassword = NO; [self.navigationController pushViewController:VC animated:YES];
3. 仿安卓Toast
#import #import //声明定义一个ToastLabel对象 @interface ToastLabel : UILabel - (void)setMessageText:(NSString *)text; @end @interface Toast : NSObject { ToastLabel *toastLabel; NSTimer *countTimer; NSInteger changeCount; } //创建声明单例的方法 + (instancetype)shareInstance; - (void)makeToast:(NSString *)message duration:(CGFloat )duation; @end #import "Toast.h" @implementation ToastLabel /** * ToastLabel初始化,位label设置各种属性 * * @return ToastLabel */ - (instancetype)init{ self = [super init]; if (self) { self.layer.cornerRadius = 10; self.layer.masksToBounds = YES; self.backgroundColor = [UIColor blackColor]; self.numberOfLines = 0; self.textAlignment = NSTextAlignmentCenter; self.textColor = [UIColor whiteColor]; self.font = [UIFont systemFontOfSize:15]; } return self; } /** * 设置显示的文字 * * @aram text 文字文本 */ - (void)setMessageText:(NSString *)text{ [self setText:text]; CGRect rect = [self.text boundingRectWithSize:CGSizeMake(DeviceWidth - 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:self.font} context:nil]; CGFloat width = rect.size.width + 20; CGFloat height = rect.size.height + 20; CGFloat x = (DeviceWidth - width) / 2; CGFloat y = DeviceHight - height - 80; self.frame = CGRectMake(x, y, width, height); } @end @implementation Toast /** * 实现声明单例的方法 GCD * * @return 单例 */ + (instancetype)shareInstance{ static Toast *singleton = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ singleton = [[Toast alloc] init]; }); return singleton; } /** * 初始化方法 * * @return 自身 * */ - (instancetype)init{ self = [super init]; if (self) { toastLabel = [[ToastLabel alloc] init]; countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeTime) userInfo:nil repeats:YES]; countTimer.fireDate = [NSDate distantFuture];//关闭定时器 } return self; } /** * 弹出并显示Tosat * * @param message 显示的文本内容 * @param duration 显示时间 */ - (void)makeToast:(NSString *)message duration:(CGFloat)duation{ if ([message length] == 0) { return; } [toastLabel setMessageText:message]; [[[UIApplication sharedApplication]keyWindow ] addSubview:toastLabel]; toastLabel.alpha = 0.8; countTimer.fireDate = [NSDate distantPast];//开启定时器 changeCount = duation; } /** * 定时器回调方法 */ - (void)changeTime{ //NSLog(@"时间:%ld",changeCount); if (changeCount-- <= 0) { countTimer.fireDate = [NSDate distantFuture];//关闭定时器 [UIView animateWithDuration:0.2f animations:^{ toastLabel.alpha = 0; } completion:^(BOOL finished) { [toastLabel removeFromSuperview]; }]; } } @end //duration:显示的时长 [[Toast shareInstance] makeToast:@"你提示的内容" duration:1.0];
4. UITextField的左视图设置
//1.创建UITextField类别 #import @interface loginUITextField : UITextField @end //2.重写UITextField的左视图的Bounds #import "loginUITextField.h" @implementation loginUITextField - (CGRect)leftViewRectForBounds:(CGRect)bounds { CGRect rect = [super leftViewRectForBounds:bounds]; if (self.window.frame.size.width == 320) { rect = CGRectMake(rect.origin.x + 3, rect.origin.y , 28, 28); } else if (self.window.frame.size.width == 375){ rect = CGRectMake(rect.origin.x + 4, rect.origin.y , 32, 32); } else { rect = CGRectMake(rect.origin.x + 5, rect.origin.y , 35, 35); } return rect; } @end //以下是例子 并不能直接使用 //_userTextField的左视图 UIImageView *useImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"user"]]; _userImageView.contentMode = UIViewContentModeScaleAspectFit; _userTextField.leftView = useImageView; _userTextField.leftViewMode = UITextFieldViewModeAlways; _userTextField.borderStyle = UITextBorderStyleRoundedRect; //修改水印字体颜色和字体大小 [_userTextField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"]; [_userTextField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"]; //_passwordTxetField的左视图 UIImageView *passwdImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"locked"]]; //passwdImageView.frame = CGRectMake(0, 0, 37, 37); _passwordTxetField.contentMode = UIViewContentModeScaleAspectFit; _passwordTxetField.leftView = passwdImageView; _passwordTxetField.leftViewMode = UITextFieldViewModeAlways; _passwordTxetField.borderStyle = UITextBorderStyleRoundedRect; //修改水印字体颜色和字体大小 [_passwordTxetField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"]; [_passwordTxetField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"];
5. 自定义NavgationBar的标题和返回按钮无文字的样式和设置NavgationBar的背景图
//自定义NavgationBar的标题 - (void)creatdTitle{ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 45)]; label.text = @"标题"; label.font = [UIFont boldSystemFontOfSize:20]; label.textAlignment = NSTextAlignmentCenter; label.textColor = [UIColor whiteColor]; self.navigationItem.titleView = label; } //返回按钮无文字的样式 - (void)createdbackBarButtonItem{ UIBarButtonItem *newBarButtonItem = [[UIBarButtonItem alloc] init]; newBarButtonItem.title = @""; self.navigationItem.backBarButtonItem = newBarButtonItem; [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]]; } //设置NavgationBar的背景图 (jpg记得加后缀) [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:UIBarMetricsDefault];
6. 自定义UIAlertController的标题、内容、和按钮的字体样式
- (void)created{ NSString *str = @"注 销"; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:str preferredStyle:UIAlertControllerStyleAlert]; NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:str]; [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, str.length)]; [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:25] range:NSMakeRange(0, str.length)]; [alertController setValue:alertControllerStr forKey:@"attributedMessage"]; UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]; [cancelAction setValue:[UIColor grayColor] forKey:@"titleTextColor"]; [alertController addAction:confirmAction]; [alertController addAction:cancelAction]; [self presentViewController:alertController animated:YES completion:nil]; }
系统的会闪">7. 验证码倒计时60S(注意UIButton样式不能用系统的会闪)
//self.verificationBtn:改成你自己的命名的button - (void)startTime{ __block int timeout = 59; //倒计时时间 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue); dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行 dispatch_source_set_event_handler(_timer, ^{ if(timeout<=0){ //倒计时结束,关闭 dispatch_source_cancel(_timer); dispatch_async(dispatch_get_main_queue(), ^{ //设置界面的按钮显示 根据自己需求设置(倒计时结束后调用) [self.verificationBtn setTitle:@"获取验证码" forState:UIControlStateNormal]; [self.verificationBtn setBackgroundColor:[UIColor colorWithRed: 0/256.0 green: 111/256.0 blue: 255/256.0 alpha:1]]; //设置可点击 self.verificationBtn.userInteractionEnabled = YES; }); }else{ // int minutes = timeout / 60; //这里注释掉了,这个是用来测试多于60秒时计算分钟的。 int seconds = timeout % 60; NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds]; dispatch_async(dispatch_get_main_queue(), ^{ //设置界面的按钮显示 根据自己需求设置 //NSLog(@"____%@",strTime); [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1]; [self.verificationBtn setTitle:[NSString stringWithFormat:@"%@秒重新发送",strTime] forState:UIControlStateNormal]; [UIView commitAnimations]; self.verificationBtn.backgroundColor = [UIColor lightGrayColor]; //设置不可点击 self.verificationBtn.userInteractionEnabled = NO; }); timeout--; } }); dispatch_resume(_timer); }
8. 各种切圆角(基本上能切得都这样切)
//头像图片切圆 _userImageView.layer.cornerRadius = _userImageView.frame.size.width / 2; _userImageView.layer.masksToBounds = YES; // _textFiled.layer.cornerRadius = 10; _textFiled.layer.masksToBounds = YES; // view.layer.cornerRadius = 20; view.layer.masksToBounds = YES;
9.避免程序因为NSNull而导致奔溃
//创建个类别 #import @interface NSNull (IsNull) @end #import "NSNull+IsNull.h" @implementation NSNull (IsNull) - (void)forwardInvocation:(NSInvocation *)invocation { if ([self respondsToSelector:[invocation selector]]) { [invocation invokeWithTarget:self]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSMethodSignature *sig = [[NSNull class] instanceMethodSignatureForSelector:selector]; if(sig == nil) { sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"]; } return sig; } @end
10.AFNetworking的一个小问题(获取数据的类型不对时,进行更改)
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain",@"text/html",@"image/jpg",nil];
11.极光推送程序内的代码
//1.创建一个类 #import #import @interface CFPushHelper : NSObject ///---------------------------------------------------- /// @name Setup 启动相关 ///---------------------------------------------------- + (NSString *)registrationID; /*! * @abstract 启动SDK * * @param launchingOption 启动参数. * @param appKey 一个JPush 应用必须的,唯一的标识. 请参考 JPush 相关说明文档来获取这个标识. * @param channel 发布渠道. 可选. * @param isProduction 是否生产环境. 如果为开发状态,设置为 NO; 如果为生产状态,应改为 YES. * @param advertisingIdentifier 广告标识符(IDFA) 如果不需要使用IDFA,传nil. * * @discussion 提供SDK启动必须的参数, 来启动 SDK. * 此接口必须在 App 启动时调用, 否则 JPush SDK 将无法正常工作. */ + (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId; ///---------------------------------------------------- /// @name APNs about 通知相关 ///---------------------------------------------------- /*! * @abstract 注册要处理的远程通知类型 * * @param types 通知类型 * @param categories * * @discussion */ //+ (void)registerForRemoteNotificationTypes:(NSUInteger)types // categories:(NSSet *)categories; //上传deviceToken + (void)registerDeviceToken:(NSData *)deviceToken; /*! * @abstract 处理收到的 APNs 消息 */ //+ (void)handleRemoteNotification:(NSDictionary *)userInfo; // ios7以后,才有completion,否则传nil + (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion; /*! * @abstract 前台展示本地推送 * * @param notification 本地推送对象 * @param notificationKey 需要前台显示的本地推送通知的标示符 * * @discussion 默认App在前台运行时不会进行弹窗,在程序接收通知调用此接口可实现指定的推送弹窗。 */ + (void)showLocalNotificationAtFront:(UILocalNotification *)notification identifierKey:(NSString *)notificationKey; @end //导入极光推送头文件@"JPUSHService.h" #import "CFPushHelper.h" #import "JPUSHService.h" @implementation CFPushHelper + (NSString *)registrationID{ return [JPUSHService registrationID]; } + (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId{ //Required if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { //可以添加自定义categories [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil]; } else { //categories 必须为nil [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil]; } //Required // 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。 [JPUSHService setupWithOption:launchingOption appKey:appKey channel:channel apsForProduction:isProduction advertisingIdentifier:advertisingId]; return; } + (void)registerDeviceToken:(NSData *)deviceToken{ [JPUSHService registerDeviceToken:deviceToken]; return; } //+ (void)handleRemoteNotification:(NSDictionary *)userInfo{ // // [CFPushHelper handleRemoteNotification:userInfo]; // //} + (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion{ [JPUSHService handleRemoteNotification:userInfo]; if (completion) { completion(UIBackgroundFetchResultNewData); } return; } + (void)showLocalNotificationAtFront:(UILocalNotification *)notification identifierKey:(NSString *)notificationKey{ [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil]; return; } @end //我这里创建的AppDelegate的类别 #import "AppDelegate.h" @interface AppDelegate (CFPushSDK) - (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; @end #import "AppDelegate+CFPushSDK.h" #import "JPUSHService.h" #import "CFPushHelper.h" #define JPushSDK_AppKey @"顾名思义" #define isProduction NO @implementation AppDelegate (CFPushSDK) - (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ [CFPushHelper setupWithOption:launchOptions appKey:JPushSDK_AppKey channel:nil apsForProduction:isProduction advertisingIdentifier:nil]; //注册 NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidLoginNotification object:nil]; } //通知方法 - (void)networkDidReceiveMessage:(NSNotification *)notification { //调用接口 NSLog(@"\n\n极光推送注册成功\n\n"); //通知后台registrationID //NSLog(@"registrationID2 = %@",[CFPushHelper registrationID]); NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (![CFPushHelper registrationID]) { NSString *registrationID = @"123"; [defaults setObject:registrationID forKey:@"registrationID"]; } else { [defaults setObject:[CFPushHelper registrationID] forKey:@"registrationID"]; } [defaults synchronize]; //[CFPushHelper registrationID] //注销通知 [[NSNotificationCenter defaultCenter] removeObserver:self name:kJPFNetworkDidLoginNotification object:nil]; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { /// Required - 注册 DeviceToken //NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]); [CFPushHelper registerDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // IOS 7 Support Required [CFPushHelper handleRemoteNotification:userInfo completion:completionHandler]; // 应用正处理前台状态下,不会收到推送消息,因此在此处需要额外处理一下 if (application.applicationState == UIApplicationStateActive) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"收到推送消息" message:userInfo[@"aps"][@"alert"] delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定",nil]; [alert show]; } //[self gotoViewControllerWith:userInfo]; [self gotoViewController]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ //NSLog(@"did Fail To Register For Remote Notifications With Error : %@",error); return; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil]; return; } - (void)applicationDidBecomeActive:(UIApplication *)application{ [application setApplicationIconBadgeNumber:0]; [application cancelAllLocalNotifications]; return; } @end #import "AppDelegate.h" #import "JPUSHService.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //注册极光推送 [self JPushapplication:application didFinishLaunchingWithOptions:launchOptions]; return YES; }
暂时就这样