03-導(dǎo)航欄設(shè)置

導(dǎo)航欄設(shè)置

課程目標(biāo)

  • 便利構(gòu)造函數(shù)的使用
  • 自定義顯示到 XIB 控制面板的屬性
  • 自定義導(dǎo)航控制器思路

發(fā)現(xiàn)頁(yè)面搜索框

課程目標(biāo)

  • 明確 Xib 創(chuàng)建視圖的流程
  • IBInspectable&IBDesignable使用

代碼實(shí)現(xiàn)

  • 新建 HMDiscoverSearchView 繼承于 UIView
class HMDiscoverSearchView: UIView,UITextFieldDelegate {

}
  • 新建 Xib 文件 HMDiscoverSearchView.xib
  1. 拖入 UITextField 作輸入框
  • 拖入 UIButton 作取消按鈕
  • 添加相關(guān)約束
  • 指定 class 為 HMDiscoverSearchView
  • 連線
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var cancelButton: UIButton!
  • HMDiscoverSearchView 提供類方法通過 xib 創(chuàng)建 view
class func searchView() -> HMDiscoverSearchView {
    let view = NSBundle.mainBundle().loadNibNamed("HMDiscoverSearchView", owner: nil, options: nil).last! as! HMDiscoverSearchView
    return view;
}
  • HMDiscoverTableViewController 添加方法,測(cè)試此View的顯示
private func setupUI(){
    let searchView = HMDiscoverSearchView.searchView()
    searchView.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, 35)
    navigationItem.titleView = searchView
}
  • 設(shè)置 textfield 的左邊放大鏡視圖
private lazy var leftImage: UIImageView = {
    return UIImageView(image: UIImage(named: "searchbar_textfield_search_icon")!)
}()

...
override func awakeFromNib() {
    // 設(shè)置 textField 的左邊視圖
    leftImage.frame = CGRectMake(0, 0, frame.height, frame.height)
    leftImage.contentMode = .Center
    textField.leftView = leftImage
    // 設(shè)置顯示模型
    textField.leftViewMode = UITextFieldViewMode.Always
}
  • 設(shè)置 textField 的代理,實(shí)現(xiàn)代理方法
class HMDiscoverSearchView: UIView,UITextFieldDelegate {
    ...

    func textFieldDidBeginEditing(textField: UITextField) {

    }
}

  • 拖入 textfield 右邊的約束到 view 中,在開始編輯的時(shí)候執(zhí)行動(dòng)畫
@IBOutlet weak var textFieldRightCons: NSLayoutConstraint!
  • 執(zhí)行約束動(dòng)畫需要調(diào)用 view 的 layoutIfNeed
func textFieldDidBeginEditing(textField: UITextField) {
    textFieldRightCons.constant = cancelButton.frame.width
    // 執(zhí)行動(dòng)畫
    UIView.animateWithDuration(0.25) { () -> Void in
        self.textField.layoutIfNeeded()
    }
}
  • 拖入取消按鈕的點(diǎn)擊事件,點(diǎn)擊的時(shí)候取消第一響應(yīng)者并執(zhí)行動(dòng)畫
@IBAction func cancelButtonClick(sender: UIButton) {
    textField.resignFirstResponder()
    textFieldRightCons.constant = 0

    // 執(zhí)行動(dòng)畫
    UIView.animateWithDuration(0.25) { () -> Void in
        self.textField.layoutIfNeeded()
    }
}

IBInspectable & IBDesignable

IBInspectable

  • 其修飾的屬性可以在 XIB/SB 右邊控制面板顯示
  • 可以重寫該屬性的 get/set 方法做自己的操作

IBDesignable

  • 其修飾自定義 View
  • 可以在更改 IBInspectable 修飾的屬性的時(shí)候動(dòng)態(tài)在 XIB/SB 里面渲染

圖片填充模式

圖片填充模式.png

UIBarButtonItem抽取

  • 快速構(gòu)造一個(gè) UIBarButtonItem
// item 上的文字顏色,高亮顏色,字體大小
// 導(dǎo)航欄上左右的文字一般都會(huì)統(tǒng)一,所以可以定義成常量
private let ItemNormalColor = UIColor(red: 80/255, green: 80/255, blue: 80/255, alpha: 1)
private let ItemHighlightedColor = UIColor.orangeColor()
private let ItemFontSize: CGFloat = 14

extension UIBarButtonItem {

    /// 快速構(gòu)造一個(gè) UIBarButtonItem
    ///
    /// - parameter imgName: 圖片名字
    /// - parameter title:   標(biāo)題文字
    /// - parameter target:
    /// - parameter action:
    ///
    /// - returns: UIBarButtonItem
    convenience init(imgName: String? = nil,title: String? = nil, target: AnyObject?, action: Selector){
        self.init()

        let button = UIButton()
        button.addTarget(target, action: action, forControlEvents: .TouchUpInside)

        // 如果有圖片,設(shè)置圖片
        if let img = imgName {
            button.setImage(UIImage(named: img), forState: UIControlState.Normal)
            button.setImage(UIImage(named: "\(img)_highlighted"), forState: UIControlState.Highlighted)
        }

        // 如果有文字,設(shè)置文字
        if let t = title {
            button.setTitle(t, forState: UIControlState.Normal)
            button.titleLabel?.font = UIFont.systemFontOfSize(ItemFontSize)
            button.setTitleColor(UIColor(red: 80/255, green: 80/255, blue: 80/255, alpha: 1), forState: .Normal)
            button.setTitleColor(UIColor.orangeColor(), forState: .Highlighted)
        }
        button.sizeToFit()

        customView = button

    }
}

自定義導(dǎo)航控制器

課程目標(biāo)

自定義 UINavigationController,實(shí)現(xiàn)新浪微博左上角返回按鈕邏輯

  • 如果是從一級(jí)頁(yè)面進(jìn)入到二級(jí)頁(yè)面,第二級(jí)頁(yè)面左上角返回按鈕顯示一級(jí)頁(yè)面的title
  • 如果是從二級(jí)頁(yè)面進(jìn)入到三級(jí)頁(yè)面(或者層次更深),進(jìn)入頁(yè)面的左上角返回按鈕顯示返回

分析

  • 如果要在每一個(gè)控制器里面分別設(shè)置的話,代碼煩瑣而且擴(kuò)展性不強(qiáng),所以寫一個(gè)自己的 UINavigationController
  • 新push進(jìn)入的控制器都會(huì)經(jīng)過 UINavigationControllerpushViewController(viewController: UIViewController, animated: Bool) 方法
  • 可以在這個(gè)方法里面判斷當(dāng)前是 push 進(jìn)入的是第幾級(jí)控制器,并設(shè)置不同的返回按鈕title

代碼

import UIKit

class HMNavigationController: UINavigationController {

    /**
    重寫此方法,在里面統(tǒng)一返回按鈕邏輯

    - parameter viewController: 將要push進(jìn)來的控制器
    - parameter animated:       是否需要?jiǎng)赢?    */
    override func pushViewController(viewController: UIViewController, animated: Bool) {

        // 如果當(dāng)前里面有控制器,才執(zhí)行下面的邏輯
        if childViewControllers.count > 0 {

            var title = "返回"

            if childViewControllers.count == 1 {
                //正要往里面添加第二個(gè)控制器
                title = childViewControllers.first?.title ?? "返回"
            }
            // push第二個(gè)或者以后控制器隱藏底部tabBar
            viewController.hidesBottomBarWhenPushed = true
            // 設(shè)置左邊item
            viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(imgName: "navigationbar_back_withtext", title: title, target: self, action: "back")

        }
        super.pushViewController(viewController, animated: animated)
    }

    @objc private func back(){
        popViewControllerAnimated(true)
    }
}

在 HMMainViewController 添加子控制器的地方,使用自己定義的導(dǎo)航控制器

  • 默認(rèn)push控制器的時(shí)候,頂部右邊會(huì)出現(xiàn)部分陰影:
navigationBar-bug.png

解決方法:

// 給tabBar(或者navigationBar)設(shè)置一張背景圖片
// HMMainViewController->ViewDidLoad()方法里面
let tab = HMTabBar()
// 設(shè)置撰寫按鈕點(diǎn)擊的事件響應(yīng)
tab.composeButtonClickBlock = {
    print("撰寫按鈕點(diǎn)擊")
}
// 設(shè)置背景圖片,去掉頂部陰影的效果
tab.backgroundImage = UIImage(named: "tabbar_background")
setValue(tab, forKey: "tabBar")

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容