填坑记(UI)

1. tableView刷新闪屏

场景:类似于聊天界面,快速多次发送消息,刷新界面并且滚动到最后一条
问题scrollToRowAtIndexPath:滚动到最后时,会再次出现从上往下滚动的现象
原因:在tableview滚动到最后一条前,还未得出cellheight,就已经开始新的reloadData
解决
tableView.estimatedRowHeight = 0
参考链接
https://www.jianshu.com/p/ef815c336ded

2. 打开webView的同时 输入框 获取焦点并弹出键盘

问题:h5页面已设置页面中input获取焦点,安卓端展示正常,但是iOS不能显示光标和键盘???????
原因:在WebView中, 默认是需要用户操作行为才能打开键盘,若需要打开页面的同时输入框获取焦点并弹出键盘,需要设置keyboardDisplayRequiresUserAction属性告知webView
解决

2.1 UIWebView
        webView.keyboardDisplayRequiresUserAction = NO;
2.1 WKWebView

OC 语言:

@implementation WKWebView (Keyboard)

static void (*originalIMP)(id self, SEL _cmd, void* arg0, BOOL arg1, BOOL arg2, id arg3) = NULL;

void interceptIMP (id self, SEL _cmd, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
    originalIMP(self, _cmd, arg0, TRUE, arg2, arg3);
}

//该函数只能调用一次,否则会导致循环调用,程序崩溃
+ (void)wkWebViewShowKeybord{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = NSClassFromString(@"WKContentView");
        SEL originalSelector = NSSelectorFromString(@"_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
        Method originalMethod = class_getInstanceMethod(cls, originalSelector);
        IMP impOvverride = (IMP) interceptIMP;
        originalIMP = (void *)method_getImplementation(originalMethod);
        method_setImplementation(originalMethod, impOvverride);
    });
}

@end

swift语言(extension中添加属性):

import WebKit

typealias ClosureType =  @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any) -> Void

extension WKWebView{
    var keyboardDisplayRequiresUserAction: Bool {
        get {
            return true
        } set {
            if newValue == false {
                setKeyboardRequiresUserInteraction()
            }
        }
    }
    
    func setKeyboardRequiresUserInteraction() {
        let sel: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:")
        let WKContentView: AnyClass = NSClassFromString("WKContentView")!
        let method = class_getInstanceMethod(WKContentView, sel)
        let originalImp: IMP = method_getImplementation(method!)
        let original: ClosureType = unsafeBitCast(originalImp, to: ClosureType.self)
        let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Any) -> Void = {(me, arg0, arg1, arg2, arg3) in
            original(me, sel, arg0, true, arg2, arg3)
        }
        let imp: IMP = imp_implementationWithBlock(block)
        method_setImplementation(method!, imp)
    }
}

参考链接:https://blog.csdn.net/longshihua/article/details/78001336

3. UIAlertController在pad上崩溃

问题UIAlertControllerpreferredStyleactionSheet时在pad上crash,iphone上正常
原因:在iPad下ActionSheet将以popover的形式展现出来
解决:设置sourceViewsourceRect属性

alertVC.popoverPresentationController?.sourceView = view
let sourceRect = CGRect.init(x: view.width / 2.0, y: view.height, width: 1, height: 1)
alertVC.popoverPresentationController?.sourceRect = sourceRect
4. 拨打电话openUrl

问题:调用拨打电话的方法openUrl,在iOS10以上出现卡顿,或阻塞其他弹窗的正常消失/出现
原因:在iOS10以上openUrl被deprecated,调用时卡了主线程
解决:区分iOS系统,10以上和以下调用不同的方法

// 拨打电话
    public class func callTelephone(phoneNum : String) -> Bool {
        let urlStr = "telprompt://\(phoneNum)"
        guard let url = URL.init(string: urlStr), UIApplication.shared.canOpenURL(url) else {
            return false
        }
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(url)
        }
        return true
    }
5. interactivePopGestureRecognizer 页面卡死或无响应

问题:在navigationController管理的第一个主页面PageA,使用“边缘手势-从左侧向右滑动”,点击通过push进入下一页面PageB,页面卡死
原因
解决:关闭主页面PageA的边缘手势
1)设置边缘手势是否开启-当是主页面时,关闭边缘手势

//设置,返回手势是否可用
    func setGestureEnable(enable: Bool) {
        guard let navi = navigationController else { return }
        if navi.viewControllers.count >= 2, enable {
            navi.interactivePopGestureRecognizer?.isEnabled = true
            navi.interactivePopGestureRecognizer?.delegate = self
        } else {
            navi.interactivePopGestureRecognizer?.isEnabled = false
            navi.interactivePopGestureRecognizer?.delegate = nil
        }
    }

2)实现代理方法

extension UIViewController: UIGestureRecognizerDelegate {
    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

3)调用方法 - 在viewDidAppear方法中调用

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        setGestureEnable(enable: true)
    }

注:不能在viewWillAppear中调用,否则在跳转到PageB页面后,使用手势侧滑返回时,页面会卡死

你可能感兴趣的:(填坑记(UI))