Реализация скользящего представления, подобного центру управления, в Swift

#swift #uiview #uigesturerecognizer #control-center

#swift #uiview #uigesturerecognizer #центр управления

Вопрос:

Я пытаюсь создать интерактивный скользящий переход в приложении.

Цель состоит в том, чтобы представить uiview при просмотре контроллера, который будет перетаскиваться снизу (а не с нижнего края, чтобы он не конфликтовал с центром управления) и будет частично перекрывать основной контроллер представления (точно так же, как центр управления iOS). Переход должен быть интерактивным, т.Е. в соответствии с перетаскиванием пользователя.

Был бы рад услышать идеи относительно доступных API.

Комментарии:

1. Я делал это раньше, у меня нет кода, но я мог бы отправить его, когда вернусь домой, если вы все еще будете без ответа.

2. Спасибо @JacobKing за ваш быстрый ответ, я жду вашего ответа.

3. @JacobKing не могли бы вы поделиться кодом

4. @user6520705 Я больше не работаю в компании, поэтому у меня нет доступа к их репозиторию управления версиями… Возможно, у меня есть старая локальная копия, но я сомневаюсь в этом, посмотрю, когда у меня будет шанс.

Ответ №1:

Следующий код выполнит простой код анимации слайд-шоу, протестированный в Xcode 8 и работающий..

  import UIKit

class ViewController: UIViewController,UIGestureRecognizerDelegate {

// I am using VisualView as a slideView
@IBOutlet weak var slideView: UIVisualEffectView!

//Button to open slideView
@IBOutlet weak var button: UIBarButtonItem!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // setting background for sideView
       slideView.backgroundColor = UIColor(patternImage: UIImage(named: "original.jpg")!)

    //Initial hide so it won't show.when the mainView loads...
      slideView.isHidden = true

    // DownSwipe to hide slideView
       let downSwipe = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.handleSwipes(_:)))
       downSwipe.direction = .down
       view.addGestureRecognizer(downSwipe)
    }

   // set UIButton to open slideVie...(I am using UIBarButton)
     @IBAction func sdrawButton(_ sender: AnyObject) {

      self.slideView.isHidden = false
      slideView.center.y  = view.frame.height

      UIView.animate(withDuration: 0.7, delay: 0, options: UIViewAnimationOptions.curveEaseIn, animations:{
        self.slideView.center.y -= self.view.frame.height
        self.button.isEnabled = false
        }, completion: nil)  
}

   func handleSwipes(_ sender:UISwipeGestureRecognizer) {
    if (sender.direction == .down) {
        print("Swipe Down")

        self.slideView.isHidden = true

        self.slideView.center.y -= self.view.frame.height
        UIView.animate(withDuration: 0.7, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations:{
            self.slideView.center.y  = self.view.frame.height
            self.button.isEnabled = true
            }, completion: nil)
  }  
  }
  }
  

Дайте мне знать, что код работает для вас…

Ответ №2:

Извините, если этот вопрос немного устарел. Вы можете подклассировать UIView и переопределить touchesBegan(_ , with), чтобы сохранить исходное местоположение касания

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  guard let  touch = touches.first else { print("No touch"); return }
      startPoint = touch.location(in: self)
      startHeight = heightConstraint.constant
      slideDirection = .none
      super.touchesBegan(touches, with: event)
   }
  

}

и коснитесь Moved(_, with), чтобы обновить ограничение высоты, пока палец перемещает вид.

 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
  guard let touch = touches.first else { print("touchesMovedno touches"); return }

  let endPoint = touch.location(in: self)
  let diff = endPoint.y - startPoint.y

  // This causes the view to move along the drag
  switch anchorLocation {
  case .top :
     heightConstraint.constant = startHeight   diff
  case .bottom :
     heightConstraint.constant = startHeight - diff
  }
  self.layoutIfNeeded()

  // Update direction
  if diff == 0.0 {
     self.slideDirection = .none
  } else {
     self.slideDirection = (diff > 0) ? .down : .up
  }
  super.touchesMoved(touches, with: event) 
  

}

Переопределите touchesEnded(_, with), чтобы добавить анимацию, если хотите

 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

  self.modifyHeightConstraints()
  self.animateViewTransition(duration: animDuration, delay: animDelay, clearance: animClearance, springDampingRatio: animSpringDampingRatio, initialSpringVelocity: animInitialSpringVelocity, complete: {
     self.slideDirection = .none
  })
  super.touchesEnded(touches, with: event)
  

}

Я создал компонент, который может иметь именно ту функцию, которую вы хотели. Компонент включает в себя настраиваемый анимированный отскок. Вы можете компоновать и создавать вложенные представления в представлении в раскадровке.

Проверьте ссылку в GitHub

https://github.com/narumolp/NMPAnchorOverlayView