亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

IOS實戰之自定義轉場動畫詳解

2020-07-26 03:28:00
字體:
來源:轉載
供稿:網友

轉場動畫這事,說簡單也簡單,可以通過presentViewController:animated:completion:和dismissViewControllerAnimated:completion:這一組函數以模態視圖的方式展現、隱藏視圖。如果用到了navigationController,還可以調用pushViewController:animated:和popViewController這一組函數將新的視圖控制器壓棧、彈棧。

下圖中所有轉場動畫都是自定義的動畫,這些效果如果不用自定義動畫則很難甚至無法實現:

由于錄屏的原因,有些效果無法完全展現,比如它其實還支持橫屏。

自定義轉場動畫的效果實現起來比較復雜,如果僅僅是拷貝一份能夠運行的代碼卻不懂其中原理,就有可能帶來各種隱藏的bug。本文由淺入深介紹下面幾個知識:

1、傳統的基于閉包的實現方式及其缺點
2、自定義present轉場動畫
3、交互式(Interactive)轉場動畫
4、轉場協調器與UIModalPresentationCustom
5、UINavigationController轉場動畫

在開始正式的教程前,您首先需要下載demo,在代碼面前文字是蒼白的,demo中包含的注釋足以解釋本文所有的知識點。其次,您還得了解這幾個背景知識。

From和To
在代碼和文字中,經常會出現fromView和toView。如果錯誤的理解它們的含義會導致動畫邏輯完全錯誤。fromView表示當前視圖,toView表示要跳轉到的視圖。如果是從A視圖控制器present到B,則A是from,B是to。從B視圖控制器dismiss到A時,B變成了from,A是to。用一張圖表示:

Presented和Presengting
這也是一組相對的概念,它容易與fromView和toView混淆。簡單來說,它不受present或dismiss的影響,如果是從A視圖控制器present到B,那么A總是presentedViewController,B總是presentingViewController。

modalPresentationStyle
這是一個枚舉類型,表示present時動畫的類型。其中可以自定義動畫效果的只有兩種:FullScreen和Custom,兩者的區別在于FullScreen會移除fromView,而Custom不會。比如文章開頭的gif中,第三個動畫效果就是Custom。

基于block的動畫
最簡單的轉場動畫是使用transitionFromViewController方法:

這個方法雖然已經過時,但是對它的分析有助于后面知識的理解。它一共有6個參數,前兩個表示從哪個VC開始,跳轉到哪個VC,中間兩個參數表示動畫的時間和選項。最后兩個參數表示動畫的具體實現細節和回調閉包。

這六個參數其實就是一次轉場動畫所必備的六個元素。它們可以分為兩組,前兩個參數為一組,表示頁面的跳轉關系,后面四個為一組,表示動畫的執行邏輯。

這個方法的缺點之一是可自定義程度不高(在后面您會發現能自定義的不僅僅是動畫方式),另一個缺點則是重用性不好,也可以說是耦合度比較大。

在最后兩個閉包參數中,可以預見的是fromViewController和toViewController參數都會被用到,而且他們是動畫的關鍵。假設視圖控制器A可以跳轉到B、C、D、E、F,而且跳轉動畫基本相似,您會發現transitionFromViewController方法要被復制多次,每次只會修改少量內容。

自定義present轉場動畫
出于解耦和提高可自定義程度的考慮,我們來學習轉場動畫的正確使用姿勢。

首先要了解一個關鍵概念:轉場動畫代理,它是一個實現了UIViewControllerTransitioningDelegate協議的對象。我們需要自己實現這個對象,它的作用是為UIKit提供以下幾個對象中的一個或多個:

1、Animator:

它是實現了UIViewControllerAnimatedTransitioning協議的對象,用于控制動畫的持續時間和動畫展示邏輯,代理可以為present和dismiss過程分別提供Animator,也可以提供同一個Animator。

交互式Animator:和Animator類似,不過它是交互式的,后面會有詳細介紹

Presentation控制器:

它可以對present過程更加徹底的自定義,比如修改被展示視圖的大小,新增自定義視圖等,后面會有詳細介紹。

在這一小節中,我們首先介紹最簡單的Animator。回顧一下轉場動畫必備的6個元素,它們被分為兩組,彼此之間沒有關聯。Animator的作用等同于第二組的四個元素,也就是說對于同一個Animator,可以適用于A跳轉B,也可以適用于A跳轉C。它表示一種通用的頁面跳轉時的動畫邏輯,不受限于具體的視圖控制器。

如果您讀懂了這段話,整個自定義的轉場動畫邏輯就很清楚了,以視圖控制器A跳轉到B為例:

  • 創建動畫代理,在事情比較簡單時,A自己就可以作為代理
  • 設置B的transitioningDelegate為步驟1中創建的代理對象
  • 調用presentViewController:animated:completion:并把參數animated設置為true
  • 系統會找到代理中提供的Animator,由Animator負責動畫邏輯

用具體的例子解釋就是:

// 這個類相當于Aclass CrossDissolveFirstViewController: UIViewController, UIViewControllerTransitioningDelegate {  // 這個對象相當于B  crossDissolveSecondViewController.transitioningDelegate = self   // 點擊按鈕觸發的函數  func animationButtonDidClicked() {    self.presentViewController(crossDissolveSecondViewController,              animated: true, completion: nil)  }  // 下面這兩個函數定義在UIViewControllerTransitioningDelegate協議中  // 用于為present和dismiss提供animator  func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {//    也可以使用CrossDissolveAnimator,動畫效果各有不同//    return CrossDissolveAnimator()    return HalfWaySpringAnimator()  }  func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {    return CrossDissolveAnimator()  }}

動畫的關鍵在于animator如何實現,它實現了UIViewControllerAnimatedTransitioning協議,至少需要實現兩個方法,我建議您仔細閱讀animateTransition方法中的注釋,它是整個動畫邏輯的核心:

class HalfWaySpringAnimator: NSObject, UIViewControllerAnimatedTransitioning {  /// 設置動畫的持續時間  func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {    return 2  }  /// 設置動畫的進行方式,附有詳細注釋,demo中其他地方的這個方法不再解釋  func animateTransition(transitionContext: UIViewControllerContextTransitioning) {    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)    let containerView = transitionContext.containerView()    // 需要關注一下from/to和presented/presenting的關系    // For a Presentation:    //   fromView = The presenting view.    //   toView  = The presented view.    // For a Dismissal:    //   fromView = The presented view.    //   toView  = The presenting view.    var fromView = fromViewController?.view    var toView = toViewController?.view    // iOS8引入了viewForKey方法,盡可能使用這個方法而不是直接訪問controller的view屬性    // 比如在form sheet樣式中,我們為presentedViewController的view添加陰影或其他decoration,animator會對整個decoration view    // 添加動畫效果,而此時presentedViewController的view只是decoration view的一個子視圖    if transitionContext.respondsToSelector(Selector("viewForKey:")) {      fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)      toView = transitionContext.viewForKey(UITransitionContextToViewKey)    }    // 我們讓toview的origin.y在屏幕的一半處,這樣它從屏幕的中間位置彈起而不是從屏幕底部彈起,彈起過程中逐漸變為不透明    toView?.frame = CGRectMake(fromView!.frame.origin.x, fromView!.frame.maxY / 2, fromView!.frame.width, fromView!.frame.height)    toView?.alpha = 0.0    // 在present和,dismiss時,必須將toview添加到視圖層次中    containerView?.addSubview(toView!)    let transitionDuration = self.transitionDuration(transitionContext)    // 使用spring動畫,有彈簧效果,動畫結束后一定要調用completeTransition方法    UIView.animateWithDuration(transitionDuration, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: .CurveLinear, animations: { () -> Void in      toView!.alpha = 1.0   // 逐漸變為不透明      toView?.frame = transitionContext.finalFrameForViewController(toViewController!)  // 移動到指定位置      }) { (finished: Bool) -> Void in        let wasCancelled = transitionContext.transitionWasCancelled()        transitionContext.completeTransition(!wasCancelled)    }  }}

animateTransition方法的核心則是從轉場動畫上下文獲取必要的信息以完成動畫。上下文是一個實現了UIViewControllerContextTransitioning的對象,它的作用在于為animateTransition方法提供必備的信息。您不應該緩存任何關于動畫的信息,而是應該總是從轉場動畫上下文中獲取(比如fromView和toView),這樣可以保證總是獲取到最新的、正確的信息。

獲取到足夠信息后,我們調用UIView.animateWithDuration方法把動畫交給Core Animation處理。千萬不要忘記在動畫調用結束后,執行completeTransition方法。

本節的知識在Demo的Cross Dissolve文件夾中有詳細的代碼。其中有兩個animator文件,這說明我們可以為present和dismiss提供同一個animator,或者分別提供各自對應的animator。如果兩者動畫效果類似,您可以共用同一個animator,惟一的區別在于:

  • present時,要把toView加入到container的視圖層級。
  • dismiss時,要把fromView從container的視圖層級中移除。

如果您被前面這一大段代碼和知識弄暈了,或者暫時用不到這些具體的知識,您至少需要記住自定義動畫的基本原理和流程:

  • 設置將要跳轉到的視圖控制器(presentedViewController)的transitioningDelegate
  • 充當代理的對象可以是源視圖控制器(presentingViewController),也可以是自己創建的對象,它需要為轉場動畫提供一個animator對象。
  • animator對象的animateTransition是整個動畫的核心邏輯。

交互式(Interactive)轉場動畫
剛剛我們說到,設置了toViewController的transitioningDelegate屬性并且present時,UIKit會從代理處獲取animator,其實這里還有一個細節:UIKit還會調用代理的interactionControllerForPresentation:方法來獲取交互式控制器,如果得到了nil則執行非交互式動畫,這就回到了上一節的內容。

如果獲取到了不是nil的對象,那么UIKit不會調用animator的animateTransition方法,而是調用交互式控制器(還記得前面介紹動畫代理的示意圖么,交互式動畫控制器和animator是平級關系)的startInteractiveTransition:方法。

所謂的交互式動畫,通常是基于手勢驅動,產生一個動畫完成的百分比來控制動畫效果(文章開頭的gif中第二個動畫效果)。整個動畫不再是一次性、連貫的完成,而是在任何時候都可以改變百分比甚至取消。這需要一個實現了UIPercentDrivenInteractiveTransition協議的交互式動畫控制器和animator協同工作。這看上去是一個非常復雜的任務,但UIKit已經封裝了足夠多細節,我們只需要在交互式動畫控制器和中定義一個時間處理函數(比如處理滑動手勢),然后在接收到新的事件時,計算動畫完成的百分比并且調用updateInteractiveTransition來更新動畫進度即可。

用下面這段代碼簡單表示一下整個流程(刪除了部分細節和注釋,請不要以此為正確參考),完整的代碼請參考demo中的Interactivity文件夾:

// 這個相當于fromViewControllerclass InteractivityFirstViewController: UIViewController {   // 這個相當于toViewController  lazy var interactivitySecondViewController: InteractivitySecondViewController = InteractivitySecondViewController()  // 定義了一個InteractivityTransitionDelegate類作為代理  lazy var customTransitionDelegate: InteractivityTransitionDelegate = InteractivityTransitionDelegate()  override func viewDidLoad() {    super.viewDidLoad()    setupView() // 主要是一些UI控件的布局,可以無視其實現細節    /// 設置動畫代理,這個代理比較復雜,所以我們新建了一個代理對象而不是讓self作為代理    interactivitySecondViewController.transitioningDelegate = customTransitionDelegate  }  // 觸發手勢時,也會調用animationButtonDidClicked方法  func interactiveTransitionRecognizerAction(sender: UIScreenEdgePanGestureRecognizer) {    if sender.state == .Began {      self.animationButtonDidClicked(sender)    }  }  func animationButtonDidClicked(sender: AnyObject) {    self.presentViewController(interactivitySecondViewController, animated: true, completion: nil)  }}

非交互式的動畫代理只需要為present和dismiss提供animator即可,但是在交互式的動畫代理中,還需要為present和dismiss提供交互式動畫控制器:

class InteractivityTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {  func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {    return InteractivityTransitionAnimator(targetEdge: targetEdge)  }  func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {    return InteractivityTransitionAnimator(targetEdge: targetEdge)  }  /// 前兩個函數和淡入淡出demo中的實現一致  /// 后兩個函數用于實現交互式動畫  func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {    return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)  }  func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {    return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)  }}

animator中的代碼略去,它和非交互式動畫中的animator類似。因為交互式的動畫只是一種錦上添花,它必須支持非交互式的動畫,比如這個例子中,點擊按鈕依然出發的是非交互式的動畫,只是手勢滑動才會觸發交互式動畫。

class TransitionInteractionController: UIPercentDrivenInteractiveTransition {  /// 當手勢有滑動時觸發這個函數  func gestureRecognizeDidUpdate(gestureRecognizer: UIScreenEdgePanGestureRecognizer) {    switch gestureRecognizer.state {    case .Began: break    case .Changed: self.updateInteractiveTransition(self.percentForGesture(gestureRecognizer)) //手勢滑動,更新百分比    case .Ended:  // 滑動結束,判斷是否超過一半,如果是則完成剩下的動畫,否則取消動畫      if self.percentForGesture(gestureRecognizer) >= 0.5 {        self.finishInteractiveTransition()      }      else {        self.cancelInteractiveTransition()      }    default: self.cancelInteractiveTransition()    }  }  private func percentForGesture(gesture: UIScreenEdgePanGestureRecognizer) -> CGFloat {    let percent = 根據gesture計算得出    return percent  }}

交互式動畫是在非交互式動畫的基礎上實現的,我們需要創建一個繼承自UIPercentDrivenInteractiveTransition類型的子類,并且在動畫代理中返回這個類型的實例對象。

在這個類型中,監聽手勢(或者下載進度等等)的時間變化,然后調用percentForGesture方法更新動畫進度即可。

轉場協調器與UIModalPresentationCustom
在進行轉場動畫的同時,您還可以進行一些同步的,額外的動畫,比如文章開頭gif中的第三個例子。presentedView和presentingView可以更改自身的視圖層級,添加額外的效果(陰影,圓角)。UIKit使用轉成協調器來管理這些額外的動畫。您可以通過需要產生動畫效果的視圖控制器的transitionCoordinator屬性來獲取轉場協調器,轉場協調器只在轉場動畫的執行過程中存在。

想要完成gif中第三個例子的效果,我們還需要使用UIModalPresentationStyle.Custom來代替.FullScreen。因為后者會移除fromViewController,這顯然不符合需求。

當present的方式為.Custom時,我們還可以使用UIPresentationController更加徹底的控制轉場動畫的效果。一個 presentation controller具備以下幾個功能:

  • 設置presentedViewController的視圖大小
  • 添加自定義視圖來改變presentedView的外觀
  • 為任何自定義的視圖提供轉場動畫效果
  • 根據size class進行響應式布局

您可以認為,. FullScreen以及其他present風格都是swift為我們實現提供好的,它們是.Custom的特例。而.Custom允許我們更加自由的定義轉場動畫效果。

UIPresentationController提供了四個函數來定義present和dismiss動畫開始前后的操作:

  • presentationTransitionWillBegin: present將要執行時
  • presentationTransitionDidEnd:present執行結束后
  • dismissalTransitionWillBegin:dismiss將要執行時
  • dismissalTransitionDidEnd:dismiss執行結束后

下面的代碼簡要描述了gif中第三個動畫效果的實現原理,您可以在demo的Custom Presentation文件夾下查看完成代碼:

// 這個相當于fromViewControllerclass CustomPresentationFirstViewController: UIViewController {  // 這個相當于toViewController  lazy var customPresentationSecondViewController: CustomPresentationSecondViewController = CustomPresentationSecondViewController()  // 創建PresentationController  lazy var customPresentationController: CustomPresentationController = CustomPresentationController(presentedViewController: self.customPresentationSecondViewController, presentingViewController: self)  override func viewDidLoad() {    super.viewDidLoad()    setupView() // 主要是一些UI控件的布局,可以無視其實現細節    // 設置轉場動畫代理    customPresentationSecondViewController.transitioningDelegate = customPresentationController  }  override func didReceiveMemoryWarning() {    super.didReceiveMemoryWarning()    // Dispose of any resources that can be recreated.  }  func animationButtonDidClicked() {    self.presentViewController(customPresentationSecondViewController, animated: true, completion: nil)  }}

重點在于如何實現CustomPresentationController這個類:

class CustomPresentationController: UIPresentationController, UIViewControllerTransitioningDelegate {  var presentationWrappingView: UIView? // 這個視圖封裝了原視圖,添加了陰影和圓角效果  var dimmingView: UIView? = nil // alpha為0.5的黑色蒙版  // 告訴UIKit為哪個視圖添加動畫效果  override func presentedView() -> UIView? {    return self.presentationWrappingView  }}// 四個方法自定義轉場動畫發生前后的操作extension CustomPresentationController {  override func presentationTransitionWillBegin() {    // 設置presentationWrappingView和dimmingView的UI效果    let transitionCoordinator = self.presentingViewController.transitionCoordinator()    self.dimmingView?.alpha = 0    // 通過轉場協調器執行同步的動畫效果    transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) -> Void in      self.dimmingView?.alpha = 0.5      }, completion: nil)  }  /// present結束時,把dimmingView和wrappingView都清空,這些臨時視圖用不到了  override func presentationTransitionDidEnd(completed: Bool) {    if !completed {      self.presentationWrappingView = nil      self.dimmingView = nil    }  }  /// dismiss開始時,讓dimmingView完全透明,這個動畫和animator中的動畫同時發生  override func dismissalTransitionWillBegin() {    let transitionCoordinator = self.presentingViewController.transitionCoordinator()    transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) -> Void in      self.dimmingView?.alpha = 0      }, completion: nil)  }  /// dismiss結束時,把dimmingView和wrappingView都清空,這些臨時視圖用不到了  override func dismissalTransitionDidEnd(completed: Bool) {    if completed {      self.presentationWrappingView = nil      self.dimmingView = nil    }  }}extension CustomPresentationController {}

除此以外,這個類還要處理子視圖布局相關的邏輯。它作為動畫代理,還需要為動畫提供animator對象,詳細代碼請在demo的Custom Presentation文件夾下閱讀。

UINavigationController轉場動畫
到目前為止,所有轉場動畫都是適用于present和dismiss的,其實UINavigationController也可以自定義轉場動畫。兩者是平行關系,很多都可以類比過來:

class FromViewController: UIViewController, UINavigationControllerDelegate {  let toViewController: ToViewController = ToViewController()  override func viewDidLoad() {    super.viewDidLoad()    setupView() // 主要是一些UI控件的布局,可以無視其實現細節    self.navigationController.delegate = self  }}

與present/dismiss不同的時,現在視圖控制器實現的是UINavigationControllerDelegate協議,讓自己成為navigationController的代理。這個協議類似于此前的UIViewControllerTransitioningDelegate協議。

FromViewController實現UINavigationControllerDelegate協議的具體操作如下:

func navigationController(navigationController: UINavigationController,    animationControllerForOperation operation: UINavigationControllerOperation,            fromViewController fromVC: UIViewController,              toViewController toVC: UIViewController)             -> UIViewControllerAnimatedTransitioning? {    if operation == .Push {      return PushAnimator()    }    if operation == .Pop {      return PopAnimator()    }    return nil;  }

至于animator,就和此前沒有任何區別了??梢姡粋€封裝得很好的animator,不僅能在present/dismiss時使用,甚至還可以在push/pop時使用。

UINavigationController也可以添加交互式轉場動畫,原理也和此前類似。

總結
對于非交互式動畫,需要設置presentedViewController的transitioningDelegate屬性,這個代理需要為present和dismiss提供animator。在animator中規定了動畫的持續時間和表現邏輯。

對于交互式動畫,需要在此前的基礎上,由transitioningDelegate屬性提供交互式動畫控制器。在控制器中進行事件處理,然后更新動畫完成進度。

對于自定義動畫,可以通過UIPresentationController中的四個函數自定義動畫執行前后的效果,可以修改presentedViewController的大小、外觀并同步執行其他的動畫。

自定義動畫的水還是比較深,本文僅適合做入門學習用,歡迎互相交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产美女精品视频免费观看| 日韩国产一区三区| 亚洲天堂男人的天堂| 亚洲香蕉成人av网站在线观看| 中文字幕亚洲欧美一区二区三区| 日韩精品视频在线观看网址| 国模gogo一区二区大胆私拍| 久久久亚洲影院| 午夜精品一区二区三区av| 狠狠躁天天躁日日躁欧美| 91sao在线观看国产| 亚洲自拍偷拍网址| 亚洲欧美国产精品va在线观看| 91久久久久久久久| 欧美在线视频在线播放完整版免费观看| 亚洲网站在线看| 国产在线观看不卡| 北条麻妃一区二区在线观看| 亚洲一级免费视频| 欧美精品性视频| 亚洲色图av在线| 亚洲va国产va天堂va久久| 久久久噜噜噜久噜久久| 麻豆国产va免费精品高清在线| 欧美丝袜一区二区三区| 亚洲国产精品嫩草影院久久| 亚洲精品中文字幕av| 美日韩丰满少妇在线观看| 亚洲石原莉奈一区二区在线观看| 中文字幕日韩欧美精品在线观看| 国产拍精品一二三| 亚洲高清久久久久久| 深夜成人在线观看| 国产欧美婷婷中文| 欧美激情高清视频| 亚洲一区二区三区视频| 91精品国产91久久久久久久久| 97婷婷涩涩精品一区| 亚洲日本中文字幕免费在线不卡| 国产综合在线观看视频| 精品magnet| 国产精品午夜国产小视频| 欧美激情精品在线| 精品久久久久久电影| 91干在线观看| 亚洲3p在线观看| 亚洲一区二区三区视频| 国产一区二区在线免费视频| 久久综合久久八八| 欧美性xxxxxxxxx| 国产精品高清在线观看| 亚洲天堂男人天堂| 亚洲aa在线观看| 97福利一区二区| 欧美影院久久久| 5566日本婷婷色中文字幕97| 97婷婷大伊香蕉精品视频| 日韩欧美在线观看| 久久久久久12| 国产成人在线精品| 欧美日韩中文在线| 亚洲网址你懂得| 美日韩精品免费观看视频| 97色在线视频观看| 久久久久国产精品www| 精品电影在线观看| 日韩成人在线视频网站| 精品香蕉在线观看视频一| 欧美日韩另类视频| 国产精品美女在线观看| 国产精品天天狠天天看| 欧美日韩免费区域视频在线观看| 美女黄色丝袜一区| 91国自产精品中文字幕亚洲| 欧美视频在线看| 欧美亚州一区二区三区| 亚洲国产古装精品网站| 日韩av电影院| 国产成人一区二区三区电影| 亚洲欧美日韩精品久久亚洲区| 成人美女免费网站视频| 国产自产女人91一区在线观看| 97视频国产在线| 日韩不卡在线观看| 午夜精品久久久久久久99黑人| 亚洲成人999| 欧美成人免费小视频| 26uuu日韩精品一区二区| 久久久91精品| 亚洲国产精品成人va在线观看| 97涩涩爰在线观看亚洲| 欧美视频在线观看 亚洲欧| 国产福利视频一区二区| 国产精品成人品| 日本a级片电影一区二区| 97色在线观看| 欧美成人全部免费| 日韩h在线观看| 中文字幕亚洲综合久久| 中文一区二区视频| 久久久av网站| 欧美精品在线视频观看| 国产精品福利观看| 中文字幕亚洲综合久久筱田步美| 97在线视频国产| 一区二区欧美日韩视频| 国产精品av在线| 国产女人18毛片水18精品| 不卡中文字幕av| 欧美福利视频网站| 68精品国产免费久久久久久婷婷| 中文字幕精品av| 亚洲精品中文字幕女同| 国产成人激情视频| 国产亚洲成精品久久| 久久久免费观看| 国产欧美日韩亚洲精品| 国产精品电影在线观看| 亚洲视频精品在线| 精品国产电影一区| 国内精品在线一区| 96精品久久久久中文字幕| 亚洲免费av片| 亚洲精品久久久一区二区三区| 亚洲国语精品自产拍在线观看| 黑人极品videos精品欧美裸| 一区二区三区视频免费| 一区三区二区视频| 欧美丰满少妇xxxxx| 欧美成人在线免费视频| 国产精品入口福利| 日韩欧亚中文在线| 国模精品一区二区三区色天香| 久久久久久免费精品| 3344国产精品免费看| 欧美精品video| 日韩电影中文 亚洲精品乱码| 亚洲人成电影网| 国产在线精品成人一区二区三区| 成人免费网站在线看| 欧美另类老女人| 精品久久久久久久中文字幕| 亚洲精品有码在线| 久久久久久这里只有精品| 国产精品视频久久| 亚洲va欧美va国产综合剧情| 欧美一区二区三区免费观看| 日韩视频―中文字幕| 久久综合免费视频影院| 亚洲欧美日韩在线一区| 国产精品综合久久久| 久久精品国产亚洲精品2020| 羞羞色国产精品| 日韩风俗一区 二区| 永久555www成人免费| 538国产精品一区二区在线| 欧美体内谢she精2性欧美| 久久手机精品视频| 欧美麻豆久久久久久中文| 91高潮在线观看| 亚洲人高潮女人毛茸茸| 51精品国产黑色丝袜高跟鞋| 精品毛片三在线观看| 亚洲免费成人av电影|