美文网首页
闲杂知识

闲杂知识

作者: mkb2 | 来源:发表于2017-10-16 12:30 被阅读52次

好久没有写博客了,原因有三:
1.使用了马克飞象+印象笔记使用,使用前者markdown写东西,直接上传到后者。看起来非常的舒服。
2.最近40天比较忙。一直开发公司项目
3.最近忙里偷闲,一直在做iOS逆向开发,也就没有去将逆向的事情记录博客供大家分享~

这段时间确实遇到了好多问题。很幸运是过去没有开发过的东西,虽然自己已经记录在了印象笔记上了。但是感觉还是应该分享一下,供其他人使用

tap:

  • 1.手机拍照之后,获取照片方向旋转 90度,使用了分类不好使的原因.
  • 2.获取照片或者相机的权限问题详解
  • 3.位置权限未开启,如何跳转到正确的设置页面(系统级别和自己的app级别)
  • 4.导航栏设置背景及导航栏滑动透明的功能实现
  • 5.statusBar的两种隐藏方式和区别
  • 6.使用NSBundle获取不到照片的问题
  • 7.弱约束
  • 8.适配ios11的位置权限以及坑,提交的坑

1.手机拍照使用分类不好使问题(裁剪方形照片)

话说项目中经常有自定义相机的功能.那么可定会获取到一个偏移90度的问题。这个网上说的都有点烂大街了.
具体原因可以参照这篇博客.讲述的非常的详细.

但是我在项目中用的时候,使用了文章里面提供的分类---也就是所有人提供的同一份分类不起作用!!!
最后发现是我获取手机方向出了错误。获取到的手机方向UIDevice.currentDevice.orientation永远是.portrait(上).我就给特别的那么。无论如何去移动自己的手机,方向都是(上)。

后来问题前辈,才知道,原因是因为手机的方向锁定设置成了“锁定状态”,所以获取的数据永远是.portrait.

屏幕锁定了
问题是手机屏幕锁定打开了。只要关闭即可

PS:如果想监听手机方向。应该去添加通知,
注意: 必须保证手机屏幕锁定是关闭的,否则方向改变,通知也不会发送

    //1.当前的摄像的方向
    fileprivate var crtOri:UIDeviceOrientation = UIDevice.current.orientation

    //2.添加通知
    fileprivate func setupNotification(){
        
    NotificationCenter.default.addObserver(self,
                                               selector: #selector(receiveScreenOrientationChange(_:)),
                                               name: NSNotification.Name.UIDeviceOrientationDidChange,
                                               object: nil)
    }
   //实时更新具体的方向
    @objc fileprivate func receiveScreenOrientationChange(_ noti:Notification){
        crtOri = UIDevice.current.orientation
    }

   //3.移除通知
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

2.获取照片或者相机的权限问题详解

获取照片这个应该是比较常见的话题。但是还是值得在说一下

请求AVCaptureDevice相机的权限的两个方法

    @available(iOS 7.0, *)
    open class func authorizationStatus(forMediaType mediaType: String!) -> AVAuthorizationStatus

    open class func requestAccess(forMediaType mediaType: String!, completionHandler handler: ((Bool) -> Swift.Void)!)

相机的授权状态分为以下几种

public enum AVAuthorizationStatus : Int {
    //用户未决定,也就是还没有弹出来系统的alert.还没有询问过用户是否授权
    case notDetermined
   //受限制
    case restricted
   //用户不允许
    case denied
   //用户同意
    case authorized
}
第一次询问

获取授权有上边两个方法。也是有一定区别的。
前者是可以获取到具体的状态类型的。是枚举值,但是当第一次处理alert的时候,我们获取的结果是未决定,当我们点击了不允许或者是。无法获取到点击了那一个。这很尴尬.

但是如果使用了第二种发生请求,就可以获取到成功还是失败,他的返回值是bool,非常的方便使用。
当系统第一次询问的时候,我们给出了选择之后,他才会打印结果,授权或者不

        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { (result) in
            print("权限=  \(result)")
            if result == true{
                let imgPickerVC = UIImagePickerController.init()
                imgPickerVC.sourceType = .camera
                self.present(imgPickerVC, animated: true, completion: nil)
            }
            
        }
    }

//打印结果
权限=  true

PS:相册授权,和位置授权同理


3.位置权限未开启,如何跳转到正确的设置页面(系统级别和自己的app级别)

如果发现定位没有授权,也就是denied状态.那么我们应该进入设置页面去设置
其实定位为授权,分为两种:
1.这个系统都未授权 let enable = CLLocationManager.locationServicesEnabled()
2.对该app未授权 .denied

所以处理定位的未授权的时候,应该注意一下。根据不同的情况跳转到不同的设置页面去,一个是系统级的设置页面,一个是app级别的设置页面

    fileprivate func checkLocationAuthor(){
        let enable = CLLocationManager.locationServicesEnabled()
        
        guard enable == true else {
            //弹出一个咨询框
            showOpenSystemLocationAlert()
            return
        }
        
        let state = CLLocationManager.authorizationStatus()
        switch state {
        case .notDetermined:
            //弹出决定框
            self.locMgr.requestWhenInUseAuthorization()
            return
        case .restricted:
            buttonState = .failed
            //弹出一个咨询框
            showGetAuthAlert()
            return
        case .denied:
            buttonState = .failed
            //弹出一个咨询框
            showGetAuthAlert()
            return
        default:
            buttonState = .loading
            //去定位当前位置
            self.locMgr.startUpdatingLocation()
        }
    }
    
    fileprivate func showOpenSystemLocationAlert(){
        let alertView = LRAlertView.init(frame: LRScreenBounds)
        alertView.show(with: .doubleButton,
                       title: "温馨提示",
                       subTitle: nil,
                       content: LROpenSystemLocationNoticeKey,
                       buttonBlock: { (index) in
            if index == 1{
                if #available(iOS 10.0, *) {
                    let string = "App-Prefs:root=Privacy&path=LOCATION"
                    let url = URL.init(string:string)
                    UIApplication.shared.open(url!, options: [:], completionHandler: { (comp) in
                        print("打开成功")
                    })
                } else {
                    let string = "prefs:root=LOCATION_SERVICES"
                    let url = URL.init(string:string)
                    if UIApplication.shared.canOpenURL(url!) {
                        UIApplication.shared.openURL(url!)
                    }
                }
            }else{
                print("取消选中")
            }
        }, btnStrs: "取消#查看设置")
        
    }
    
    fileprivate func showGetAuthAlert(){
        let alertView = LRAlertView.init(frame: LRScreenBounds)
        alertView.show(with: .doubleButton,
                       title: "温馨提示",
                       subTitle: nil,
                       content: LROpenLemonRunLocationNoticeKey,
                       buttonBlock: { (index) in
            if index == 1{
                let string = UIApplicationOpenSettingsURLString
                let url = URL.init(string:string)
                UIApplication.shared.openURL(url!)
            }else{
                print("取消选中")
            }
        }, btnStrs: "取消#查看设置")
    }

iOS10以上的使用"App-Prefs:root=Privacy&path=LOCATION"跳转到系统级别的设置页面,打开之后,所有的app都可以使用位置权限了
iOS10以下,使用"prefs:root=LOCATION_SERVICES跳转到系统级别的设置页面

如果是跳转到自己的项目中的设置页面,只要传递UIApplicationOpenSettingsURLString字符串即可


4.导航栏设置背景及导航栏滑动透明的功能实现

导航栏比较特殊,所以直接设置他的背景颜色啥的。也是有一层毛玻璃,这个问题,在很多博客中都有讲述,然后使用runtime就可以解决这些问题。但是现在要说的是滑动效果~
参考的是这个参考github

//viewWillAppear的时候,设置导航栏的背景

    self.automaticallyAdjustsScrollViewInsets = NO;
    //设置导航条空间的透明度是没有效果的  但是可以设置透明的背景图
    //设置为nil系统自动给你设置半透明图片
   //下面三句话,让导航栏透明了
    self.navigationController.navigationBar.alpha = 0;
    [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setShadowImage:[[UIImage alloc]init]];//导航条图片下面的线
//根据色值生成一张图片
- (UIImage *)imageWithColor:(UIColor *)color
{
    // 描述矩形
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    // 开启位图上下文
    UIGraphicsBeginImageContext(rect.size);
    // 获取位图上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 使用color演示填充上下文
    CGContextSetFillColorWithColor(context, [color CGColor]);
    // 渲染上下文
    CGContextFillRect(context, rect);
    // 从上下文中获取图片
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    // 结束上下文
    UIGraphicsEndImageContext();
    return theImage;
}

通过scrollview的偏移量修改背景的透明度

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat offset = scrollView.contentOffset.y - originY;
    CGFloat h = originH - offset;
    if (h<64) {
        h = 64;
    }
    self.topViewHeight.constant = h;
    CGFloat alpha = offset * 1 / 136.0;
    if (alpha >=1) {
        alpha = 0.99;
    }
    //拿到标题
    UILabel *titleL = (UILabel *)self.navigationItem.titleView;
    titleL.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    
    //修改导航栏的背景图片
    //把颜色生成图片
    UIColor *alphaColor = [UIColor colorWithWhite:1 alpha:alpha];
    //把颜色生成图片
    UIImage *alphaImage = [self imageWithColor:alphaColor];
    //修改导航条背景图片
    [self.navigationController.navigationBar setBackgroundImage:alphaImage forBarMetrics:UIBarMetricsDefault];
    
}

5.statusBar的两种隐藏方式和区别

文章参考
总结:

  • ①.View controller-based status bar appearance表示控制App状态栏显隐接受全局配置(NO)或者各控制器各自配置(YES)iOS9之后,建议配置成YES,各自控制器控制状态的隐藏或显示.
  • ②.[[UIApplication sharedApplication] setStatusBarHidden:YES],必须在View controller-based status bar appearance == NO条件下才能生效
  • ③.通过prefersStatusBarHidden为局部配置项,控制对应控制器状态栏显隐,必须在View controller-based status bar appearance == YES才生效。
  • ④.在启动页面应该是隐藏的状态,在plist中设置Status bar is initially hidden = YES即可.
  • ⑤.如果我们打算使用[[UIApplication sharedApplication] setStatusBarHidden:hidden]全局来控制状态栏的隐藏或显示,如果M页面要去隐藏状态栏,我们就应该在M页面做好控制.M消失的时候,应该还原,避免对其他页面的影响
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        UIApplication.shared.setStatusBarHidden(true, with: .none)
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        UIApplication.shared.setStatusBarHidden(false, with: .none)
    }
  • ⑥.[[UIApplication sharedApplication] setStatusBarHidden:hidden]方法在iOS9之后,已经不建议使用了。建议使用prefersStatusBarHidden控制。切记.

6.使用NSBundle获取不到照片的问题

同事直接将.png图片拖到了项目中,但是使用NSBundle获取不到照片。尴尬.但是用一个干净的demo测试没有问题,也不知道这个大哥是如何拖进来的。反正获取的是nil路径.

已经拖动到了项目中
 filePath = [[NSBundle mainBundle] pathForResource:@"LevelGif11" ofType:@"gif"];

问题是没有将图片加载到资源文件中

//解决
在项目设置中Build Phases > Copy Bundle Resources 
中可以查看已经添加进去的资源文件,如果里面没有,那就需要在这里手动添加了。

7.弱约束

项目中经常使用到布局。

Jietu20171011-160628.jpg

很多人非要用xib去做,然后那,又做不好~
我们要求vipicon距离“接收”按钮15dx。

其实只要去给vipIcon添加一个约束,>=15即可,这样就是“弱约束”,到时候系统自己检测即可

实际效果如图,文字一旦超过,切文字,这里没有用到任何的计算

8.适配ios11的位置权限以及坑,提交的坑

ios11之后,位置的设置权限有了很重要的改变,就是必须有三个选项
1.永不
2.使用期间
3.永远使用

但是在ios10之前可以将使用期间省略。
昨天做了适配ios11,ios上的永不,降级为使用期间,添加一个新的字段即可Privacy - Location Always and When In Use Usage Description,然后就行了,别的我没处理,保证的是在ios10上还是两个,但是在ios11上是三个。
我的是Xcode8.3.3,多哥的是Xcode9,上线之后还是不好使。

我就懵逼了,我的xcode运行就没有任何问题,但是多哥的就不好使。
区老师问我有什么思路吗?我说没有,他说,你的好事,ipa上的就不好使,说明是包出来问题,让我去看看多哥打包出来的ipa好使不好使,然后再去看其他的问题。给了我这个好的思路,然后才发现,确实是多哥xcode的问题,所以很尴尬,出问题,先想原因,然后在去做会更好一些。

相关文章

  • 闲杂知识

    好久没有写博客了,原因有三:1.使用了马克飞象+印象笔记使用,使用前者markdown写东西,直接上传到后者。看起...

  • 闲杂,

    现在是九月中旬 空气中还是夹着一丝闷热 这样的天气 我总是会饥渴到喝下一整杯水 却无法享受冰凉的水进入喉咙时的快感...

  • 闲杂

    诗中有云:“春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是人间好时节。”沐浴一缕阳光,独酌一...

  • 闲杂

    依然晴好,冷风轻抚,喜迎财神! 走亲访友,吃喝闲聊,总有说不完的家常,总有吃不厌的美食,何以不长肉。 时常关注路况...

  • PTP的一些闲杂知识

    计算机中的 system clock:system clock is maintained by the kern...

  • 闲杂小记

    杉香残桓烂泥瓦,悲伤逆流成河,柔肠夏酿雄黄覆。系古今前程渺渺,夜郎国洪荒乱渡。 藏书阁楼倚栏叹。巨浪雄狮,卷土情决...

  • 闲杂事

    最近要期末考了,一直呆在寝室看书复习。但是有好多浪费的时间,无聊了就看看综艺节目,一看就不可收拾。最近喜欢看向往的...

  • 闲杂述

    走入沉寂深山中的溶洞,方可敞开心扉。 平日无聊之时,若心可宁如止水,既无空虚,又未彷徨,则可称自己为优雅之人了。 ...

  • 春困闲杂

    暖风徐徐 吹来一缕春的困意 吹起那心间,点点涟漪 啊,春天来了,来得悄无声息 就连窗台上的花花草草 也开始打起它的...

  • 闲杂手绘

    高一第一学期 同上 高二 画画的时间越来越少。。。。。。

网友评论

      本文标题:闲杂知识

      本文链接:https://www.haomeiwen.com/subject/hnkkuxtx.html