開始用Swift開發(fā)iOS 10 - 19 使用UIPageViewController構(gòu)建介紹頁面

繼續(xù)上一篇 開始用Swift開發(fā)iOS 10 - 18 Search Bar 和 UISearchController ,這一篇使用UIPageViewController構(gòu)建介紹頁面,與使用LaunchScreen.storyboard的啟動(dòng)頁不同。

向Storyboard中添加UIPageViewController

  • 在Storyboard拖進(jìn)一個(gè)UIPageViewController。修改相關(guān)屬性。
  • 修改UIPageViewControllerstoryboard IDWalkthroughController。

類似UINavigationController,UIPageViewController也是一種容器類型的控制器。這種容器類型的控制器是用來管理其它多個(gè)控制器的。

如果容器內(nèi)的控制器頁面元素類似(上圖就是這種情況),可以通過一個(gè)控制器重復(fù)利用。

設(shè)計(jì)介紹頁

  • 下載介紹頁所需的圖片,拖到Assets.xcasset。
  • 拖動(dòng)一個(gè)新的View Controller到SB中(作為重復(fù)使用的控制器),做一些UI設(shè)計(jì):
    • 設(shè)置背景為紅色
    • 添加一個(gè)Label名為Personalize,選擇合適的字體和大小,居中。
    • 添加一個(gè)Image View,300*232,居中。
    • 添加另一個(gè)Label名為Pin your favorite restaurants and create your own food guide,282*64,行數(shù)為0,居中,選擇合適的字體和大小。
    • 添加一些約束
  • 設(shè)置新的View Controllerstoryboard IDWalkthroughContentViewController。
    最后大概如下:

創(chuàng)建WalkthroughContentViewController

  • 創(chuàng)建WalkthroughContentViewController類文件,繼承至UIViewController,并關(guān)聯(lián)上面添加的新View Controller。

  • 添加三個(gè)接口,關(guān)聯(lián)兩個(gè)Label和一個(gè)image view;添加四個(gè)變量,其中index是指多個(gè)介紹頁的索引。

    @IBOutlet var headingLabel: UILabel!
    @IBOutlet var contentLabel: UILabel!
    @IBOutlet var contentImageView: UIImageView!
    
    var index = 0
    var heading = ""
    var imageFile = ""
    var content = ""
    
  • 修改viewDidLoad為:

      override func viewDidLoad() {
          super.viewDidLoad()
    
          headingLabel.text = heading
          contentLabel.text = content
          contentImageView.image = UIImage(named: imageFile)
      }
    

實(shí)現(xiàn) UIPageViewController

  • 新建類WalkthroughPageViewController,繼承至UIPageViewController。

  • WalkthroughPageViewControlle符合UIPageViewControllerDataSource協(xié)議。

     class WalkthroughPageViewController: UIPageViewController, UIPageViewControllerDataSource 
    
  • 新建幾個(gè)變量,用于顯示介紹頁中的內(nèi)容。

      var pageHeadings = ["Personalize", "Locate", "Discover"]
      var pageImages = ["foodpin-intro-1", "foodpin-intro-2", "foodpin-intro-3"]
      var pageContent = ["Pin your favorite restaurants and create your own foodguide", "Search and locate your favourite restaurant on Maps", "Find restaurants pinned by your friends and other foodies around the world"]
    
  • 實(shí)現(xiàn)UIPageViewControllerDataSource協(xié)議的兩個(gè)方法,分別在介紹頁翻到下一個(gè)和翻到上一個(gè)時(shí)調(diào)用。contentViewController函數(shù)的作用是根據(jù)介紹頁的索引獲取不同的數(shù)據(jù)。instantiateViewController方法根據(jù)storyboard的中storyboard ID生成視圖控制器。

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
          
          var index = (viewController as! WalkthroughContentViewController).index
          index -= 1
          return contentViewController(at: index)
      }
      
      func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
          
          var index = (viewController as! WalkthroughContentViewController).index
          index += 1
          return contentViewController(at: index)
      }
      
      func contentViewController(at index: Int) -> WalkthroughContentViewController? {
          
          if index < 0 || index >= pageHeadings.count {
              return nil
          }
          
          if let pageContentViewController = storyboard?.instantiateViewController(withIdentifier: "WalkthroughContentViewController") as? WalkthroughContentViewController {
              
              pageContentViewController.imageFile = pageImages[index]
              pageContentViewController.heading = pageHeadings[index]
              pageContentViewController.content = pageContent[index]
              pageContentViewController.index = index
              
              return pageContentViewController
          }
          
          return nil
      }
    
  • 修改viewDidLoad

      override func viewDidLoad() {
          super.viewDidLoad()
    
          dataSource = self
          if let startingViewController = contentViewController(at: 0) {
              setViewControllers([startingViewController], direction: .forward, animated: true, completion: nil)
          }
      }
    

setViewControllers方法是設(shè)置UIPageViewController管理的視圖控制器。

  • 讓介紹頁在首頁顯示后跳出。 在RestaurantTableViewControlle中添加:
      override func viewDidAppear(_ animated: Bool) {
          super.viewDidAppear(animated)
          if let pageViewController = storyboard?.instantiateViewController(withIdentifier: "WalkthroughController") as? WalkthroughPageViewController {
              present(pageViewController, animated: true, completion: nil)
          }
      }
    

添加默認(rèn)頁面指示

頁面指示就是一般在頁面下用于分辨當(dāng)前是第一個(gè)頁面的幾個(gè)小點(diǎn)。
實(shí)現(xiàn)UIPageViewControllerDataSource協(xié)議的兩個(gè)方法:presentationCount(for:)表示總共有幾個(gè)小點(diǎn)(頁面)。
presentationIndex(for:)表示當(dāng)前頁面的索引。

    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return pageHeadings.count
    }
    
    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        if let pageContentViewController = storyboard?.instantiateViewController(withIdentifier: "WalkthroughContentViewController") as? WalkthroughContentViewController {
            return pageContentViewController.index
        }
        return 0
    }

修改頁面指示的樣式

不用默認(rèn)的頁面指示,就要把上面兩個(gè)方法刪除,然后使用UIPageControl。

  • 刪除上面實(shí)現(xiàn)的兩個(gè)方法。從對(duì)象庫中拖一個(gè)Page Controlwalkthrough content view controller底部,在屬性檢查器中修改適當(dāng)屬性,并添加約束。
  • WalkthroughContentViewController中添加接口@IBOutlet var pageControl: UIPageControl!并與Page Control關(guān)聯(lián)。在viewDidLoad中添加pageControl.currentPage = index

添加NEXT/DONE按鈕

  • walkthrough content view controller右下角添加一個(gè)按鈕名為NEXT。

  • WalkthroughContentViewController中添加接口,并按鈕關(guān)聯(lián)。

      @IBOutlet var forwardButton: UIButton!
    
  • viewDidLoad中添加根據(jù)索引判斷按鈕名的代碼:

          switch index {
          case 0...1: forwardButton.setTitle("NEXT", for: .normal)
          case 2: forwardButton.setTitle("DONE", for: .normal)
          default: break
          }
    
  • 添加點(diǎn)擊按鈕的action,并與按鈕關(guān)聯(lián)

      @IBAction func nextButtonTapped(sender: UIButton) {
          switch index {
          case 0...1:
              let pageViewController = parent as! WalkthroughPageViewController
              pageViewController.forward(index: index)
          case 2:
              dismiss(animated: true, completion: nil)
          default: break
          }
      }
    
  • WalkthroughPageViewController中添加方法:

      func forward(index: Int) {
          if let nextViewController = contentViewController(at: index + 1) {
              setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
          }
      }
    

完成類似下面:

但因?yàn)橹笆抢?code>RestaurantTableViewController的viewDidAppear方法顯示介紹頁的,而viewDidAppear方法是頁面顯示后就調(diào)用一下,這樣就出現(xiàn)不停進(jìn)入介紹頁。實(shí)際上只需要第一次打開app的時(shí)顯示介紹頁就可以了。

UserDefaults的使用

UserDefaults是用來管理應(yīng)用和用戶相關(guān)的設(shè)置的。也就是可以用UserDefaults存儲(chǔ)一些用戶相關(guān)的少量數(shù)據(jù),比如上面的是否看過介紹頁,也就是是否點(diǎn)擊過DONE按鈕了。
UserDefaults也是通過單例模式進(jìn)行操作的,通過類屬性standard獲取單例。

  • nextButtonTapped中點(diǎn)擊DONE按鈕時(shí)設(shè)置一個(gè)值標(biāo)志:
      @IBAction func nextButtonTapped(sender: UIButton) {
          switch index {
          case 0...1:
              let pageViewController = parent as! WalkthroughPageViewController
              pageViewController.forward(index: index)
          case 2:
              UserDefaults.standard.set(true, forKey: "hasViewedWalkthrough")
              dismiss(animated: true, completion: nil)
          default: break
          }
      }
    
  • 再到RestaurantTableViewControllerviewDidAppear判斷對(duì)應(yīng)key值。
      override func viewDidAppear(_ animated: Bool) {
          super.viewDidAppear(animated)
          
          if UserDefaults.standard.bool(forKey: "hasViewedWalkthrough") {
              return
          }
          
          if let pageViewController = storyboard?.instantiateViewController(withIdentifier: "WalkthroughController") as? WalkthroughPageViewController {
              present(pageViewController, animated: true, completion: nil)
          }
      }
    

完成介紹頁。學(xué)習(xí)了UIPageViewControllerUserDefaults。

代碼

Beginning-iOS-Programming-with-Swift

說明

此文是學(xué)習(xí)appcode網(wǎng)站出的一本書 《Beginning iOS 10 Programming with Swift》 的一篇記錄

系列文章目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容