iOS工作开发问题总结纪录 长期更新

意在记录一些开发中遇到的问题和处理方式方法 记录一些小问题的解决 以鉴需要的人 会长期更新

1、APP icon 在iPhone上可以显示 但在iPad上显示不出来

解决方法:在info.plist里删除CFBundleIcons~ipad 这个Key
iPhone项目在iPad中无法显示图标解决方法

2、生成标准的整套iOS App icon 图片(无alpha通道)

应用的图标。遵循 Apple、 Google、 Microsoft 官方标
图片工厂— 移动应用图标生成工具,一键生成所有尺寸的应用图标

3、Object/Model对象储存到NSUserDefaults

//序列化对象并储存
LHPersonModel *personModel = [[LHPersonModel alloc]init];
NSData *personData = [NSKeyedArchiver archivedDataWithRootObject: LHPersonModel];
[[NSUserDefaults standardUserDefaults] setObject:personData forKey:@"KPersonData"];
//取出数据并反序列化
NSData *personData = [[NSUserDefaults standardUserDefaults] objectForKey:@"KPersonData"];    
LHPersonModel * personModel = [NSKeyedUnarchiver unarchiveObjectWithData:personData];    
NSLog(@"Name:%@ Age:%@", personModel.name, @(personModel.age));

4、账号/密码/用户名 去除左右两侧空格

产品反馈 有用户前后多输入空格导致无法登录 空格肉眼又看不见 so 需要过滤左右空格(中间空格不过滤)让用户可以登录

NSString* str = @" [email protected]    ";     
NSString* res = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];  

iOS和Android去除字符串两边的空格

5、MKMapvie iOS苹果系统地图 获取比例尺&罗盘 更改其坐标(支持iOS11+)

//比例尺
- (void)setMapScaleBarPosition:(CGPoint)mapScaleBarPosition
{
    if (@available(iOS 11.0, *)) {
        __block MKScaleView *  mapScaleView = [self.mapView viewWithTag:11 * 11];
        if ( mapScaleView == nil) {
            mapScaleView = [MKScaleView scaleViewWithMapView:_mapView];
            mapScaleView.scaleVisibility = MKFeatureVisibilityVisible;
            mapScaleView.tag = 11 * 11;
            mapScaleView.width = 100;
            [self.mapView addSubview:mapScaleView];
        }
        
        [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
            mapScaleView.origin = mapScaleBarPosition;
        } completion:nil];

    } else {
//            _mapView.showsScale = YES;
        // Fallback on earlier versions
    }
}
//罗盘
- (void)setMapCompassPosition:(CGPoint)mapCompassPosition
{
    if (@available(iOS 11.0, *)) {
        MKCompassButton *compass = [MKCompassButton compassButtonWithMapView:(MKMapView *)self.mapView];
        compass.compassVisibility = MKFeatureVisibilityAdaptive;
        compass.origin = mapCompassPosition;
        compass.tag = 12 * 12;
        [self.mapView addSubview:compass];
    } else {
//        _mapView.showsCompass = YES;
        // Fallback on earlier versions
    }
}

6、百度坐标、国测局坐标、地球坐标之间的互转纠偏

//百度坐标转国测局坐标
+ (CLLocationCoordinate2D)baiduToGCJ02Tool:(CLLocationCoordinate2D)coodinate
{
    double x = coodinate.longitude - 0.0065, y = coodinate.latitude - 0.006;
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * earth_pi);
    double theta = atan2(y, x) - 0.000003 * cos(x * earth_pi);
    double lon = z * cos(theta);
    double lat = z * sin(theta);
    
    return CLLocationCoordinate2DMake(lat, lon);
}

//国测局坐标转百度坐标
+ (CLLocationCoordinate2D)GCJ02ToBaidu:(CLLocationCoordinate2D)coodinate
{
  double x = coodinate.longitude;
  double y = coodinate.latitude;
  double z = sqrt(x * x + y * y) + 0.00002 * sin(y * earth_pi);
  double theta = atan2(y, x) + 0.000003 * cos(x * earth_pi);
  
  double lon = z * cos(theta) + 0.0065;
  double lat = z * sin(theta) + 0.006;
  
  return CLLocationCoordinate2DMake(lat, lon);
}
//地球坐标转国测局坐标
+ (CLLocationCoordinate2D)earthToGCJ02Tool:(CLLocationCoordinate2D)coodinate{
    double dLat = [self transformLatWithLon:coodinate.longitude - 105.0 andLat:coodinate.latitude - 35.0];
    double dLon = [self transformLonWithLon:coodinate.longitude - 105.0 andLat:coodinate.latitude - 35.0];
    double radLat = coodinate.latitude / 180.0 * math_pi;
    double magic = sin(radLat);
    magic = 1 - de * magic * magic;
    double sqrtMagic = sqrt(magic);
    dLat = (dLat * 180.0) / ((a * (1 - de)) / (magic * sqrtMagic) * math_pi);
    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * math_pi);
    
    return CLLocationCoordinate2DMake(coodinate.latitude + dLat, coodinate.longitude + dLon);
}

const double math_pi = 3.14159265358979324;
const double earth_pi = 3.14159265358979324 * 3000.0 / 180.0;
const double a = 6378245.0;
const double de = 0.00669342162296594323;
+ (double)transformLatWithLon:(double)x andLat:(double)y
{
  double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x));
  ret += (20.0 * sin(6.0 * x * math_pi) + 20.0 * sin(2.0 * x * math_pi)) * 2.0 / 3.0;
  ret += (20.0 * sin(y * math_pi) + 40.0 * sin(y / 3.0 * math_pi)) * 2.0 / 3.0;
  ret += (160.0 * sin(y / 12.0 * math_pi) + 320 * sin(y * math_pi / 30.0)) * 2.0 / 3.0;
  return ret;
}

//国测局坐标转地球坐标
+ (CLLocationCoordinate2D)GCJ02ToEarthTool:(CLLocationCoordinate2D)coodinate
{
    double dLat = [self transformLatWithLon:coodinate.longitude - 105.0 andLat:coodinate.latitude - 35.0];
    double dLon = [self transformLonWithLon:coodinate.longitude - 105.0 andLat:coodinate.latitude - 35.0];
    double radLat = coodinate.latitude / 180.0 * math_pi;
    double magic = sin(radLat);
    magic = 1 - de * magic * magic;
    double sqrtMagic = sqrt(magic);
    dLat = (dLat * 180.0) / ((a * (1 - de)) / (magic * sqrtMagic) * math_pi);
    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * math_pi);
    
    return CLLocationCoordinate2DMake(coodinate.latitude - dLat, coodinate.longitude - dLon);
}

.......

7、iOS 判断当前经纬度位置coordinate 是否在中国大陆、中国台湾、中国香港

(iOS)判断GPS坐标是否在中国

8、推荐一个练习刷算法题的网站 现在也有了中国版 很nice的

LeetCode 中国

9、run-ios React Native 运行时报错

Found Xcode project AwesomeProject.xcodeproj
xcrun: error: unable to find utility "simctl", not a developer tool or in PATH

Command failed: xcrun simctl list devices
xcrun: error: unable to find utility "simctl", not a developer tool or in PATH

Xcode工具路径不对 应该是你装过两个Xcode 或者改过路径 去Xcode>preferences>Locations command line tools:

屏幕快照 2018-06-12 下午8.23.44.png

10、React-native 报错集合

如果你正在学习入门RN 建议可以遇到error可以看一下这篇文章 新手遇到的问题这里都有列举 还有其他问题可以留言 一起讨论
React Native开发错误警告处理总结

11、APP启动页时如何隐藏状态栏

在info.plits文件中添加key Status bar is initially hidden = YES
就可以啦

屏幕快照 2017-08-11 下午3.55.46.png

11、 NSPredicate 谓词的使用

OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据。非常方便。在Java中是没有这种技术的,但是有开源的框架已经实现了此功能。
NSPredicate 谓词的使用

12、切圆角的三种方式

切圆角是开发app过程中经常会用到的功能,但是使用不同的方式,性能损耗也会不同,下面会介绍3种切圆角的方法;其中,方法三的性能相对最好。

方法一:

使用cornerRadius进行切圆角,在iOS9之前会产生离屏渲染,比较消耗性能,而之后系统做了优化,则不会产生离屏渲染,但是操作最简单

iv.layer.cornerRadius = 30;
iv.layer.masksToBounds = YES;
方法二:

利用mask设置圆角,利用的是UIBezierPath和CAShapeLayer来完成

CAShapeLayer *mask1 = [[CAShapeLayer alloc] init];
mask1.opacity = 0.5;
mask1.path = [UIBezierPath bezierPathWithOvalInRect:iv.bounds].CGPath;
iv.layer.mask = mask1;
方法三:

利用CoreGraphics画一个圆形上下文,然后把图片绘制上去,得到一个圆形的图片,达到切圆角的目的。

- (UIImage *)drawCircleImage:(UIImage*)image
{
    CGFloat side = MIN(image.size.width, image.size.height);
    
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side), false, [UIScreen mainScreen].scale);
    CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, side, side)].CGPath);
    CGContextClip(UIGraphicsGetCurrentContext());
    
    CGFloat marginX = -(image.size.width - side) * 0.5;
    CGFloat marginY = -(image.size.height - side) * 0.5;
    [image drawInRect:CGRectMake(marginX, marginY, image.size.width, image.size.height)];
    
    CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
    
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

13、 蓝牙项目中遇到打开蓝牙允许“xxx”连接到配件 这个系统提示怎么关闭 CBCentralManagerOptionShowPowerAlertKey

@{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:NO]}

14、 iOS12 TableView section header/footer 间隔设置高度无效添加下面一句 配合使用

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 10.f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [UIView new];
}

15、 XCode10 组件化编译不更新或运行报错Multiple commands produce /路径

image.png

image.png

Legacy Build System 更改后生效

16、 NSMutableAttributedString 使用富文本 图片元素(NSTextAttachment)+ 文字 时不能居中对齐

富文本中使用NSMutableAttributedString 富文本字符串 实现 图片 + 文字的Label 时遇到图片在前时 整个文本不能居中对齐 正常情况下设置NSMutableParagraphStyle 文本格式就可以实现对齐效果 如下

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
    paragraphStyle.alignment = NSTextAlignmentCenter;
    
    NSMutableAttributedString *mAttStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ",insuranceText] attributes:@{NSFontAttributeName: [UIFont f12],
                                                                                                                                                         NSForegroundColorAttributeName:[UIColor colorWithHexString:@"BBBBBB"],
                                                                                                                                                         NSParagraphStyleAttributeName:paragraphStyle                                                                   }];
    

但是遇到图片在前面时不能对齐 我是这样处理的 你可以尝试一下 有更好的方式欢迎在评论中分享

//在字符串前加一个空格占位位
[@" " stringByAppendingString:insuranceText];       
//图片Attachment元素 insert插入1位置 就不会影响paragraphStyle.alignment的使用了
[mAttStr insertAttributedString:Attachment atIndex:1];

17、 Xcode 遇到报错Error: xib: Encountered an error communicating with IBAgent-iOS.

意思是与Xib通讯错误 原因也很莫名其妙 不太清楚怎么造成的 解决方法 command + k / 重启xocde / 重启电脑 一步

18、 邮箱/电话号码简单的脱密显示(dah*******@gmail.com)

NSString *account = @"[email protected]";
NSArray *accounts = [account componentsSeparatedByString:@"@"];
if (accounts.firstObject.length > 3) {
      NSString *rangeStr = [accounts.firstObject substringWithRange:NSMakeRange(0, 3)];
      NSString *str = [rangeStr stringByPaddingToLength:accounts.firstObject.length
                                                       withString:@"*"
                                                  startingAtIndex:0];
      NSString *encryptionStr = [NSString stringWithFormat:@"%@@%@",str,accounts.lastObject];
      NSLog(@"%@",encryptionStr);
      //输出:dah*******@gmail.com
}

19、根据图片Url 获取网络图片尺寸的处理方式 (准确)

之前有个需求是根据用户上传的图片链接按显示比例铺满排版
常见的处理方式是解析图片的header信息内容格式(png、jpg、gif等)来获取图片尺寸(网上很多就不列举了) 但有问题是不够准确 经常会计算错误 导致排版异常 下面这种方式可以准确的获取图片的宽高尺寸

/**
 *  根据图片url获取图片尺寸
 */
+ (CGSize)getImageSizeWithURL:(id)URL{
    NSURL * url = nil;
    if ([URL isKindOfClass:[NSURL class]]) {
        url = URL;
    }
    if ([URL isKindOfClass:[NSString class]]) {
        url = [NSURL URLWithString:URL];
    }
    if (!URL) {
        return CGSizeZero;
    }
    CGImageSourceRef imageSourceRef =     CGImageSourceCreateWithURL((CFURLRef)url, NULL);
    CGFloat width = 0, height = 0;
    if (imageSourceRef) {
        CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, NULL);
        
        if (imageProperties != NULL) {
            CFNumberRef widthNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
#if defined(__LP64__) && __LP64__
            
            if (widthNumberRef != NULL) {
                CFNumberGetValue(widthNumberRef, kCFNumberFloat64Type, &width);
            }
            CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
            if (heightNumberRef != NULL) {
                CFNumberGetValue(heightNumberRef, kCFNumberFloat64Type, &height);
            }
            
#else
            
            if (widthNumberRef != NULL) {
                CFNumberGetValue(widthNumberRef, kCFNumberFloat32Type, &width);
            }
            CFNumberRef heightNumberRef = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
            if (heightNumberRef != NULL) {
                CFNumberGetValue(heightNumberRef, kCFNumberFloat32Type, &height);
            }
            
#endif
            CFRelease(imageProperties);
        }
        CFRelease(imageSourceRef);
    }
    return CGSizeMake(width, height);
}

20、在iOS 10 装载UICollectionView / UITableView 的VC页面在push下级页面再pop回来事content内容被下压20像素

在iOS10系统中 开发时遇到push页面返回后 UICollectionView / UITableView content被下压20像素 试了下面各种属性设置并没有什么卵用

self.automaticallyAdjustsScrollViewInsets = NO;
self.edgesForExtendedLayout = UIRectEdgeNone;

后来网上有位兄dei贴出来这样一段代码

  UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 0)];
    [self.view addSubview:view];
    
    mainTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 75, SCREEN_WIDTH, 60 * 3)];
    mainTableView.backgroundColor = [UIColor yellowColor];
    mainTableView.dataSource = self;
    mainTableView.delegate = self;
    [self.view addSubview:mainTableView];

思路清奇~ 试了下问题确实得以神奇解决 但没有说明具体原因 猜测是因为safeArea 安全显示区域做的一些系统适配 会作用于第一个contentView

尝试不同的解决方式时 发现我们的TabBar因为是自定义的 NavBar也是自定义的 所以说都不是使用的系统的控件 当我尝试把VC外用UINavigtionController 包裹一层时也可以解决这个问题 猜测系统在这方面其实已经对自己的控件做了适配 所以我想说的是 不要过度自定义 这些控件完全可以遵循系统的方式来扩展

MAC VNC://使用别名连接屏幕共享失败的问题原因

首先你要确认你在偏好设置->共享->打开屏幕共享 是开启的 然后检查一下选项设置是否正确 在看一下自己的防火墙有没有开启 确认是同一个局域网
如果你设置了别名(自定义名称) 系统会在下方提示你其他用户可以通过 vnc://LH/ 或通过在“访达”边栏中查找“LH”来访问您的电脑屏幕。
但这样有可能还是链接不上 是因为你的设置了别名 别人找不到你 这时你可以通过你的网络IP来替换别名建立链接 打开网络偏好设置 用vnc访问你的IPvnc://192.168.1.18/就可以尝试屏幕共享了

21 iOS 如果让子视图View一直保持在最上层显示

    self.tableView.mj_header.layer.zPosition = MAXFLOAT;

你可能感兴趣的:(iOS工作开发问题总结纪录 长期更新)