博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 中的那些小问题
阅读量:6167 次
发布时间:2019-06-21

本文共 21243 字,大约阅读时间需要 70 分钟。

  1. UITextView 中的文字默认并不是从最上面开始,在 UITextView 所在的 UIViewController中添加:
self.automaticallyAdjustsScrollViewInsets = false;复制代码
  1. UITableView 自动隐藏键盘:
tableView.keyboardDismissMode = .onDrag复制代码
  1. 设置 UITableView 中的 Cell 选中打钩的颜色:
tableView.tintColor = .red复制代码
  1. UIButton 在边缘的时候没有高亮响应,重写 UIButton 的 pointInside函数:
/**        解决按钮在边缘的时候被按下时没有显示高亮          - parameter point: 按下的位置     - parameter event: 目标事件          - returns: 是否在内部     */    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {                let inside = super.pointInside(point, withEvent: event)                if inside != highlighted && event?.type == .Touches {            highlighted = inside        }                return inside    }复制代码

PS:如果遇到需要这样的情况下,最好继承 UIButton 重写该函数,而不是extension UIButton,因为这样会使工程中用到的所有的 UIButton 都被重写。

  1. 静音模式下播放音频,最好在didFinishLaunchingWithOptions中进行调用
/**        静音模式下仍可以播放音频    */    public class func playInQuietMode() {                let audioSession: AVAudioSession = AVAudioSession.sharedInstance()                do {            try audioSession.setCategory(AVAudioSessionCategoryPlayback)        } catch let error as NSError{            print(error)        }                do {            try audioSession.setActive(true)        } catch let error as NSError{            print(error)        }    }复制代码
  1. 自定义 UITableViewCell 选中时的颜色
/**        设置选中背景色          - parameter color: 背景色     */    public func setSelectColor(color: UIColor) {                let backgroundView = UIView();        backgroundView.backgroundColor = color;        self.selectedBackgroundView = backgroundView;    }复制代码

PS:self.selectionStyle的值不能为.None

  1. 判断 UIScrollView 是否滚动结束:
/// 记录手指放开滑动时 scrollView 的内容偏移fileprivate var offset = CGPoint.zero// 记录当前滑动状态fileprivate var isScrollEnd = trueextension Controller: UIScrollViewDelegate {        public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {        // 开始滚动,记录状态        isScrollEnd = false    }        public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {        // 记录手指放开滑动时 scrollView 的内容偏移        offset = scrollView.contentOffset        // 使用 perform 延迟检测 scrollView 内容偏移,        // 1. 如果手指放开滑动后 scrollView 继续滑动,由于 perform 运行在 NSDefaultRunLoopMode 模式,        //    因此在 scrollView 继续滑动的情况下不会开始定时,因此不会在设置的延时后调用;        // 2. 如果手指放开滑动后 scrollView 停止滑动,则会在设置的延时后调用 checkScrollEnd;        perform(#selector(self.checkScrollEnd), with: nil, afterDelay: 0.020)    }        public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {        // 当手指放开滑动后 scrollView 继续滑动,取消 checkScrollEnd 的调用;        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(self.checkScrollEnd), object: nil)        // 结束滚动,记录状态        isScrollEnd = true    }        internal func checkScrollEnd() {        // 判断 scrollView 当前内容偏移与手指松开时的内容偏移是否相同,        isScrollEnd = (offset == tableView.contentOffset)    }}复制代码
  1. UITableView 添加 UITextField 时键盘处理
/// 添加监听public override func viewDidAppear(_ animated: Bool) {    super.viewDidAppear(animated)    // 监听键盘的弹出    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil)    // 监听键盘的隐藏    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)}/// 移除监听public override func viewDidDisappear(_ animated: Bool) {    super.viewDidDisappear(animated)    NotificationCenter.default.removeObserver(self)}/// 键盘弹出处理public func keyboardDidShow(_ notification : Notification) {    // 获取当前活跃的textField及其rect    guard let textField = activeField, let rect = textField.superview?.convert(textField.frame, to: nil) else {            return    }    // 获取键盘信息    guard let keyboardInfo = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }    // 获取键盘高度    let keyboardHeight = keyboardInfo.cgRectValue.size.height;    // 获取 textField 底部剩余空间    let cellBottomHeight = UIScreen.main.bounds.height - rect.maxY    // 获取 textField 需要向上平移多少才能满足键盘弹出所需的空间    var offset = keyboardHeight - cellBottomHeight    // 设置底部偏移,保证键盘弹出后仍能滑动到底部    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)    // 当 offset 小于 0 时,表示空间已满足    guard offset > 0 else { return }    // 加上 tableView 当前偏移    offset += self.tableView.contentOffset.y    self.tableView.setContentOffset(CGPoint(x: 0, y: offset), animated: true)}/// 键盘收回处理public func keyboardWillHide(_ notification : Notification) {    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)}复制代码
  1. 给 UIView 添加阴影
/**        添加阴影          - parameter color:  阴影颜色     - parameter offset: 阴影偏移     */    public func addShadow(color: UIColor, offset: CGFloat) {                self.layer.shadowColor = color.CGColor;        self.layer.shadowOffset = CGSizeMake(-offset, offset);        self.layer.shadowOpacity = 0.8;        self.layer.shadowRadius = offset;    }复制代码
  1. 震动
/**        震动,在真机上:设置/声音 中开启响铃/震动选项开启后才能震动    */    public class func shark() {        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate));    }复制代码
  1. 打开 iPod
/**        打开 iPod     */    public class func openIpod() {                UIApplication.sharedApplication().openURL(NSURL(string: "music://")!);    }复制代码
  1. App 国际化时,有时我们第一次安装APP时不想默认跟随系统,那么可以通过Xcode的scheme来指定特定语言

  2. 让 UITableView 在没有数据时不能滚动

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {                self.tableView.scrollEnabled = (data.count > 0);                return data.count;}复制代码
  1. 应用内打开其他 App 在Info.plist文件中设置URL types
    之后就可以使用下面的模式来发送一个URL:
myapp://myapp://some/path/heremyapp://?foo=1&bar=2myapp://some/path/here?foo=1&bar=2复制代码

然后,App 的UIApplicationDelegate会收到一个消息。若你想自己处理该URL,可以重载下面这个方法:

func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool {}复制代码
  1. 如果20秒内无法启动程序的话,iOS 检测计时器就会终止你的应用

  2. UIImage+imageNamed: 方法可避免延时加载,不像 +imageWithContentsOfFile:(和其他别的 UIImage 加载方法),这个方法会在加载图片之后立刻进行解压。

  3. App 播放视频时进入后台让视频继续播放,有两种方法可以实现:

第一种、 对目标视频对象的视频轨进行以下处理:

let playerItem = AVPlayerItem(URL: NSURL(string: "videoUrl")!);let tracks = playerItem.tracks;for track in tracks {   if (track.assetTrack.hasMediaCharacteristic(AVMediaCharacteristicVisual)) {       track.enabled = false;   }}复制代码

第二种、 在进入后台前将目标视频渲染层设为 nil,在恢复到前台时重新设置:

func applicationDidEnterBackground(application: UIApplication) {    let playerView = "Get your player view";    playerView.playerLayer.player = nil; }func applicationDidBecomeActive(application: UIApplication) {   let playerView = "Get your player view";   playerView.playerLayer.player = player;}复制代码
  1. 获取视频的每秒帧数 fps 和 视频的长度 duration
let asset = AVAsset(URL: NSURL(fileURLWithPath: "videoPath"));let fps = asset.tracksWithMediaType(AVMediaTypeVideo)[0].nominalFrameRate;let duration = CMTimeGetSeconds(asset.duration);复制代码
  1. App 进入后台仍然继续运行:
public func applicationDidEnterBackground(application: UIApplication) {                application.beginReceivingRemoteControlEvents();        var bgTask : UIBackgroundTaskIdentifier?        bgTask = application.beginBackgroundTaskWithExpirationHandler {            dispatch_async(dispatch_get_main_queue(), {                if bgTask != UIBackgroundTaskInvalid                {                    bgTask = UIBackgroundTaskInvalid                }            })        }                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {            dispatch_async(dispatch_get_main_queue(), {                if bgTask != UIBackgroundTaskInvalid                {                    bgTask = UIBackgroundTaskInvalid                }            })        }    }复制代码
  1. App 运行中不锁屏:
UIApplication.sharedApplication().idleTimerDisabled = true;复制代码
  1. 禁止 oc 文件使用 ARC-fno-objc-arc

  2. Swift 获取对象的引用次数:CFGetRetainCount(obj)

  3. 禁止 UIButton 在按下时有动态阴影:

button.adjustsImageWhenHighlighted = false;复制代码
  1. 隐藏导航栏的返回按钮:
self.navigationItem.hidesBackButton = true;复制代码
  1. 隐藏导航栏下影线:
self.navigationController?.navigationBar.shadowImage = UIImage();复制代码
  1. 设置导航栏中间为图片:
self.navigationItem.titleView = UIImageView(image: UIImage(named: "titleImage"));复制代码
  1. 导航栏相关属性效果
/// rootView 的布局从(0,0)开始edgesForExtendedLayout = .allnavigationController?.navigationBar.isTranslucent = false/// rootView 的布局从(0,64)开始edgesForExtendedLayout = .allnavigationController?.navigationBar.isTranslucent = true复制代码
  1. 机型与屏幕尺寸的对应:
  • 4s_3.5inch
  • 5s_4inch
  • 6_4.7inch
  • 6+_5.5inch
  1. 模拟器截图时,必须设置分辨率为100%(Simulator > Window > Scale > 100%)

  2. UIView 中添加定时器时导致内存泄露处理:

override func willMoveToWindow(newWindow: UIWindow?) {    super.willMoveToWindow(newWindow);    if (newWindow == nil) {        self.updateTimer.invalidate();    }}复制代码
  1. UITextfiled 设置 placehold 字体颜色:
self.passwdTextIpt.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("login_passwd", comment: ""), attributes: [NSForegroundColorAttributeName: UIColor(white: 1.0, alpha: 0.4)]);复制代码
  1. 使用自定义字体

  2. 将目标字体拖入目标项目;

  3. Info.plist 文件中设置目标字体;

  4. 将字体添加到 Copy Bundle Resources

  5. 使用字体:UIFont(name: fontname, size: fontsize);

  6. 设置 UITextfiled 文字偏移:

self.userIdTextIpt.layer.sublayerTransform = CATransform3DMakeTranslation(10, 0, 0);复制代码

或者重写 UITextfiled

override func textRectForBounds(bounds: CGRect) -> CGRect {    return CGRectInset(bounds, 44, 0);}override func editingRectForBounds(bounds: CGRect) -> CGRect {    return CGRectInset(bounds, 44, 0);}复制代码
  1. UIImage 显示与图片不同,设置其渲染模式即可:
UIImage(named: imageName)!.imageWithRenderingMode(.AlwaysOriginal);复制代码
  1. 设置状态栏背景样式无效:

  2. Info.plist 文件中设置 View controller-based status bar appearanceNo

  3. Appdelegate.swift 文件中设置 UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default;

  4. 隐藏导航栏返回按钮:

self.navigationItem.hidesBackButton = true;复制代码
  1. 使用 Cookie:
let url = NSURL(string: url);guard let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL(url!) else {    return}let header = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies);let request = NSMutableURLRequest(URL: url!);request.addValue(header["Cookie"]!, forHTTPHeaderField: "Cookie");复制代码
  1. 添加阴影
view.layer.shadowColor = UIColor.blackColor().CGColor;view.layer.shadowOffset = CGSizeMake(0, 0);view.layer.shadowOpacity = 0.25;view.layer.shadowRadius = 6;复制代码
  1. 检查 API 可用性
if #available(iOS 9.0, *) {       let store = CNContactStore()} else {       // 旧版本的情况}复制代码
  1. swift 中将 Unmanaged 转化为 UIImage
let unCGimage:Unmanaged
= defaultRepresentation.fullResolutionImage();let image = unCGimage.takeUnretainedValue())复制代码
  1. CADisplayLink 使用完成后内存无法被释放:
self.displaylink = CADisplayLink(target: self, selector: #selector(SCGifView.changeKeyFrame))self.displaylink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)复制代码

以上在我一个工程中使用到的,在测试的时候,发现其内存无法被释放,检查看发现需要手动调用以下代码来完成释放:

self.displaylink?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes);self.displaylink?.invalidate();self.displaylink = nil;复制代码
  1. 设置 App 沙盒内的 Document 文件夹可以被其他软件共享(各类手机助手): 在 Info.plist 文件中 添加 Application supports iTunes file sharing,并设置其值为 YES

  2. 播放系统拍照时的 咔嚓声(本质就是播放系统声音):

let soundID: SystemSoundID = 1108;    //! 1108 就是拍照的系统声音编号,要播放其他的声音可以到网上搜索对应的编号AudioServicesPlayAlertSound(soundID);复制代码
  1. AudioServicesPlaySystemSoundAudioServicesPlayAlertSound 的区别:

    1. AudioServicesPlaySystemSound 仅仅是播放系统声音,在静音模式下不播放;
    2. AudioServicesPlayAlertSound 当设置了 通用/声音/响铃模式振动,播放系统声音并振动,否则只播放系统声音;当设置了 通用/声音/静音模式振动,振动,否则不播放系统声音。
  2. UIButton 即有文字又有图像时,只让图像旋转:

let animation = CABasicAnimation(keyPath: "transform.rotation.z");animation.fromValue = NSNumber(float: 0);animation.toValue = NSNumber(double: 2 * M_PI);animation.duration = 3;animation.repeatCount = HUGE;button.imageView?.layer.addAnimation(animation, forKey: "scRotationAnimation");复制代码
  1. 调用 AVPlayerseekToTime 接口时间不对,将
self.player!.seekToTime(CMTimeMakeWithSeconds(time, self.player!.currentItem!.currentTime().timescale));复制代码

更换为:

self.player!.seekToTime(CMTimeMakeWithSeconds(time, self.player!.currentItem!.currentTime().timescale), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero);复制代码
  1. 使用 NSDateFormatter.dateFromString 总是返回 nil,原因可能是你的时间格式是12小时制而你的值是24小时制,将 hh:mm:ss 改成 HH:mm:ss即可。

  2. swift 中结构体与结构体指针的使用,SMsgAVIoctrlSetPlayVolumeReq 为结构体, IOTYPE_USER_IPCAM_AUDIO_PLAY_VOLUME_SETTING_REQ 为枚举变量:

let cmd = UnsafeMutablePointer
(malloc(sizeof(SMsgAVIoctrlSetPlayVolumeReq)))cmd.memory.command_types_ = 1;cmd.memory.value_ = 1; self.camera.sendIOCtrlToChannel(0, type: Int(IOTYPE_USER_IPCAM_AUDIO_PLAY_VOLUME_SETTING_REQ.rawValue), data: UnsafeMutablePointer
(cmd), dataSize: sizeof(SMsgAVIoctrlSetPlayVolumeReq)) free(cmd)复制代码
  1. 指针偏移
let buf:UnsafePointer
= CFDataGetBytePtr(rawData)var r:UInt8 = 0r = buf.advancedBy(i+0).memory复制代码
  1. 字符串保留特定字符(以下例子保留字母):
let notAllowedCharactersSet = NSCharacterSet(charactersInString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdedghijklmnopqrsquvwxyz").invertedSetlet filterStr = (str.componentsSeparatedByCharactersInSet(notAllowedCharactersSet) as NSArray).componentsJoinedByString("")复制代码
extension UIButton {        class func oyc_swizzleSendAction() {                struct oyc_swizzleToken {            static var onceToken : dispatch_once_t = 0        }                dispatch_once(&oyc_swizzleToken.onceToken) {                        let cls: AnyClass! = UIButton.self                        let originalSelector = #selector(sendAction(_:to:forEvent:))            let swizzledSelector = #selector(oyc_sendAction(_:to:forEvent:))                        let originalMethod =                class_getInstanceMethod(cls, originalSelector)            let swizzledMethod =                class_getInstanceMethod(cls, swizzledSelector)                        method_exchangeImplementations(originalMethod, swizzledMethod)        }    }        public func oyc_sendAction(action: Selector, to: AnyObject!, forEvent: UIEvent!) {                struct oyc_buttonTapCounter {            static var count: Int = 0        }                oyc_buttonTapCounter.count += 1        print(oyc_buttonTapCounter.count)        oyc_sendAction(action, to: to, forEvent: forEvent)    }        override public class func initialize() {        if self != UIButton.self {            return        }        UIButton.oyc_swizzleSendAction()    }}复制代码
  1. ?? 操作符 在 Swift 中,有一个非常有用的操作符,可以用来快速地对 nil 进行条件判断,那就是 ?? 。这个操作符可以判断输入并在当左侧的值是非 nil 的 Optional 值时返回其 value,当左侧是 nil 时返回右侧的值,比如:
var level : Int?var startLevel = 1var currentLevel = level ?? startLevel复制代码
  1. App 在启动界面停留特定时间:
NSThread.sleepForTimeInterval(3.0);      // 3.0 表示 3 秒复制代码
  1. swift 中根据字符串创建对象:
//动态获取命名空间:        let nameSpace = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String        //根据命名空间和传过来的控制器名字获取控制器的类        let controllerClass:AnyClass = NSClassFromString(nameSpace + "." + controllerName)!                //告诉编译器真实的控制器类型,比如这个控制器本质是UITableViewController则:        let realClass = controllerClass as! UITableViewController.Type                //实例化这个控制器出来        let childController = realClass.init()复制代码
  1. UIButton 中的 文本图片 默认是水平对齐

  2. 使用 单元测试 时显示 Module 'CTest' was not compiled for testing: 在 Build SettingsEnable Testability 设置为 YES

  3. Xcode 8 控制台输出信息太多解决方法:Edit Scheme -> Run -> Arguments, 在 Environment Variables 里边添加 OS_ACTIVITY_MODE,值设置为 disable

  4. 设置 WKWebView 的字体大小:

        //创建网页配置对象        let config = WKWebViewConfiguration();        // 创建设置对象        let preference = WKPreferences();        // 设置字体大小(最小的字体大小)        preference.minimumFontSize = 60;        // 设置偏好设置对象        config.preferences = preference;        // 创建WKWebView        let webView = WKWebView(frame: self.view.bounds, configuration: config);        webView.loadHTMLString("

Some Text

", baseURL: nil)        return webView;复制代码
  1. 设置 WKWebView 根据屏幕宽度调整内容大小:
/// 网络浏览视图    fileprivate let webView: WKWebView = {        let source = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"        let script = WKUserScript(source: source, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)        let userContentController = WKUserContentController()        userContentController.addUserScript(script)        //创建网页配置对象        let config = WKWebViewConfiguration()        config.userContentController = userContentController        // 创建设置对象        let preference = WKPreferences()        // 设置字体大小(最小的字体大小)        preference.minimumFontSize = 18        // 设置偏好设置对象        config.preferences = preference        return WKWebView(frame: .zero, configuration: config)    }()复制代码
  1. lazy 属性本质上是一个闭包,闭包中的表达式只会调用一次。需要强调的是,虽然这个闭包中捕获了self,但是这样做并不会导致循环引用,猜测是 swift 自动把 self 标记为 unowned 了。

  2. 给视图及之上的子控件添加阴影:

let container = UIView();    container.clipsToBounds = true;    container.layer.cornerRadius = 5;    container.layer.borderWidth = 1;    container.layer.borderColor = UIColor.gray.cgColor;    container.layer.shadowColor = UIColor.black.cgColor;    container.layer.shadowOffset = CGSize(width: 4, height: 4);    container.layer.shadowOpacity = 0.5;    container.layer.shadowRadius = 3;    return container;复制代码
  1. 从项目中删除了某个目录、文件以后,编译出现警告信息: ld: warning: directory not found for option“XXXXXX” 解决办法:

  2. 选择工程,选中 TARGETS 中的目标工程

  3. 选择 Build Settings 菜单

  4. 查找 Library Search Paths 和 Framework Search Paths,删掉编译报 warning 的路径即可。

  5. 统一收起键盘:

UIApplication.shared.keyWindow?.endEditing(true);复制代码
  1. 动态创建控制器
let vcs = [RunLoopViewController.self, CDrawViewController.self] as [UIViewController.Type];let vc = self.vcs[indexPath.row].init()    // 创建控制器let vcString = NSStringFromClass(self.vcs[indexPath.row])    // 复制代码
  1. 设置 UITableView 中的 cell分隔线铺满整个 cell
let stView = UITableView();stView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);复制代码
  1. 动态修改 tableFooterView 的高度
self.footview.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: heightOfFooterView);self.tableView.tableFooterView = self.footview;    // 需要重新给 tableFooterView 赋值复制代码
  1. 获取 UILabel 设置 text 后的大小:
label.intrinsicContentSize复制代码
  1. UIButton 添加子视图后无法响应事件的处理:
let btn = UIButton();let subView = UIView(frame: btn.bounds);subView.isUserInteractionEnabled = false;     // 将子视图的用户交互禁止,这样 UIButton 就能继续响应事件btn.addSubview(subView);复制代码
  1. 使用 UISearchController 导致的黑屏问题,在使用 UISearchControllerUIViewControllerviewDidLoad 添加:
self.definesPresentationContext = true复制代码
  1. 自定义 UISearchBar 中的 UITextField 无效:必须确保 UISearchBarsearchBarStyleprominent ,当其值为 minimal 时,自定义 UITextField 无效。

  2. 手动取消 UISearchController

searchController.isActive = false复制代码
  1. 子控件(比如按钮)超出父视图部分无法响应事件,在父视图添加以下代码(其思路是遍历父视图的所有子视图,并判断触发事件的点是否在子视图的bounds内如果在就返回这个子视图。):
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {    var view = super.hitTest(point, with: event);    guard view == nil else { return view }    for subView in self.subviews {        let p = subView.convert(point, from: self);        if subView.bounds.contains(p) {            view = subView;        }    }    return view;}复制代码
  1. Xcode 无法在高于某系统的真机上运行:This iPhone 6 is running iOS 10.1 (14B55或者14B72), which may not be supported by this version of Xcode: 把升级包放在路径:应用程序(xcode)-右键-显示包内容  /Developer/Platforms/iPhoneOS.platform/DeviceSupport

  2. 在控制器 A 中,push 展示 控制器 B,这时要隐藏控制器 B 的返回按钮的文本,需要在控制器 A 中添加以下代码,而不是在控制器 B 中,因为 控制器 B 中的返回按钮实际是控制器 A 的:

self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.plain, target:nil, action:nil)复制代码
  1. 设置导航栏标题:

方式一:

self.title = "标题"          // 当控制器处于 UITabbarViewController 中时,对应的 Tabbar 项也会显示该标题复制代码

方式二:

self.navigationItem.title = "标题"          // 这样设置的话,即使当控制器处于 UITabbarViewController 中时,对应的 Tabbar 项也不会显示该标题复制代码
  1. 设置导航栏返回按钮图片:在创建导航栏的时候添加以下代码
// 绘制图片,主要是原始图片问题,可以跳过此步UIGraphicsBeginImageContextWithOptions(image.size, false, 0)image.draw(at: CGPoint(x: -10, y: 10))var backImage = UIGraphicsGetImageFromCurrentImageContext()!UIGraphicsEndImageContext()// 设置渲染模式,不设置的话,会使用系统默认颜色backImage = backImage.withRenderingMode(.alwaysOriginal);// 设置返回按钮图片self.navigationController?.navigationBar.backIndicatorImage = backImage;self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage;复制代码
  1. UITableViewCell 被点击时,subviews 消失,这是因为当 UITableViewCell 被点击时会改变它内部的 subviews 的背景色,因此重写 UITableViewCell 以下两个方法即可:
override func setSelected(_ selected: Bool, animated: Bool) {    super.setSelected(selected, animated: animated)    guard selected else { return }    subview.backgroundColor = subviewColor}override func setHighlighted(_ highlighted: Bool, animated: Bool) {    super.setHighlighted(highlighted, animated: animated)    guard highlighted else { return }    subview.backgroundColor = subviewColor}复制代码
  1. swift 3 之后,函数有返回值没有被使用的时候会报警告,在该函数前加 @discardableResult 可以让编译器不报警告

  2. 多线程

  3. 串行

    • 同步,在当前线程中按顺序执行,同时阻塞当前线程
    • 异步,新开线程,但仅新开一个线程,所有执行的任务都在同一个新开的线程中顺序执行,不会阻塞当前线程
  4. 并发

    • 同步,在当前线程中顺序执行,同时阻塞当前线程。(这个运行结果和串行队列,同步执行是一模一样的。 因为同步任务的概念就是按顺序执行,后面都要等。言外之意就是不允许多开线程。 同步和异步则是决定开一条还是开多条。)
    • 异步,每一个 async 新开一个线程(也可能多个 async 共有一个线程,具体看系统分配)并发执行,不会阻塞当前线程
  5. 总结

    • 同步/异步决定开不开新线程;
    • 只有并发异步内的任务是并发执行的;
    • 其他的都是顺序执行;
    • 主队列是一个串行队列,全局队列是一个并行队列;
    • 异步串行队列添加的任务按添加的顺序执行,在一些情况可以用来当锁,比如多线程中对数组的操作;;
  6. 使用 for in 操作序列:

// 只对非 nil 值进行循环for case let item? in seq { 	// i 将是 Int 值,而不是 Int? 	print(item)}或for case let .some(item) in seq { 	// i 将是 Int 值,而不是 Int? 	print(item)}// 只对 nil 值进行循环 for case nil in seq { 	// 将对每个 nil 执行一次	print("No value") }let j=5 if case0..<10=j{	print("\(j) 在范围内") }//5在范围内复制代码

持续更新

转载地址:http://rouba.baihongyu.com/

你可能感兴趣的文章
【全球AI人才排行榜】美国第一,中国仅排名第7
查看>>
微信小程序输入框input
查看>>
MySql字符串函数使用技巧
查看>>
Doc2Vec,Word2Vec文本相似度 初体验。
查看>>
系统ghost后变成一个盘了别的分区的文件怎么找回
查看>>
Win7+Ubuntu11
查看>>
请问华为三层交换机里面的那个从IP是个什么意思? -
查看>>
kFeedback开源啦
查看>>
大数据传输,文件传输的专业解决方案!
查看>>
阿里云专家穆轩的《杭州九年程序员之“修炼”手册》
查看>>
JQuery:deferred对象的方法
查看>>
eyoucms问答 百度权重是什么
查看>>
win10中遇到qq视频时摄像头打不开没反应的解决方法
查看>>
介绍自己的一个Android插桩热修复框架项目QuickPatch
查看>>
关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
查看>>
Solr Facet 查询
查看>>
C++类的继承一
查看>>
数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...
查看>>
巧用VMware Workstation的clone来制作虚拟机模板
查看>>
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
查看>>