#swift #uiview #uiviewcontroller #swipe
#swift #uiview #uiviewcontroller #проведите пальцем
Вопрос:
Привет, я хочу предоставить PanGecture
действие салфетки для UIView
в верхней части UIViewControllers
. для этого я пишу один общий метод в расширении контроллера представления, но он делает весь viewcontroller
свайп.
Я хочу выполнить действие прокрутки только для UIView, пожалуйста, помогите мне изменить следующий код на UIView Extension
.
extension UIViewController{
@objc func pangectureRecognizerDismissoneScreen(_ sender: UIPanGestureRecognizer){
var initialTouchPoint: CGPoint = CGPoint(x: 0,y: 0)
let touchPoint = sender.location(in: self.view?.window)
if sender.state == UIGestureRecognizerState.began {
initialTouchPoint = touchPoint
} else if sender.state == UIGestureRecognizerState.changed {
if touchPoint.y - initialTouchPoint.y > 0 {
self.view.frame = CGRect(x: 0, y: touchPoint.y - initialTouchPoint.y, width: self.view.frame.size.width, height: self.view.frame.size.height)
}
} else if sender.state == UIGestureRecognizerState.ended || sender.state == UIGestureRecognizerState.cancelled {
if touchPoint.y - initialTouchPoint.y > 100 {
self.view.backgroundColor = UIColor.clear
self.dismiss(animated: true, completion: nil)
} else {
UIView.animate(withDuration: 0.3, animations: {
self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
})
}
}
}
}
Ответ №1:
Вы можете добавить это расширение UIView
import UIKit
import RxSwift
struct AssociatedKeys {
static var actionState: UInt8 = 0
}
typealias ActionTap = () -> Void
extension UIView {
var addAction: ActionTap? {
get {
guard let value = objc_getAssociatedObject(self, amp;AssociatedKeys.actionState) as? ActionTap else {
return nil
}
return value
}
set {
objc_setAssociatedObject(self, amp;AssociatedKeys.actionState, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
self.tapWithAnimation()
}
}
func tapWithAnimation() {
self.gestureRecognizers?.removeAll()
let longTap = UILongPressGestureRecognizer(target: self, action: #selector(viewLongTap(_:)))
longTap.minimumPressDuration = 0.035
longTap.delaysTouchesBegan = true
self.addGestureRecognizer(longTap)
}
@objc
func viewLongTap(_ gesture: UILongPressGestureRecognizer) {
if gesture.state != .ended {
animateView(alpha: 0.3)
return
} else if gesture.state == .ended {
let touchLocation = gesture.location(in: self)
if self.bounds.contains(touchLocation) {
animateView(alpha: 1)
addAction?()
return
}
}
animateView(alpha: 1)
}
fileprivate func animateView(alpha: CGFloat) {
UIView.transition(with: self, duration: 0.3,
options: .transitionCrossDissolve, animations: {
self.subviews.forEach { subView in
subView.alpha = alpha
}
})
}
}
Пример:
myView.addAction = {
print("click")
}
Комментарии:
1. что такое RxSwift
2. @srikanthkumar просто игнорируйте этот импорт, я не использую этот импорт в этом расширении. RxSwift — это модуль ~> github.com/ReactiveX/RxSwift
3. Хорошо, но ваш код не проводит пальцем вниз и не закрывает представление.
Ответ №2:
Используйте это расширение класса.
//Gesture extention
extension UIGestureRecognizer {
@discardableResult convenience init(addToView targetView: UIView,
closure: @escaping () -> Void) {
self.init()
GestureTarget.add(gesture: self,
closure: closure,
toView: targetView)
}
}
fileprivate class GestureTarget: UIView {
class ClosureContainer {
weak var gesture: UIGestureRecognizer?
let closure: (() -> Void)
init(closure: @escaping () -> Void) {
self.closure = closure
}
}
var containers = [ClosureContainer]()
convenience init() {
self.init(frame: .zero)
isHidden = true
}
class func add(gesture: UIGestureRecognizer, closure: @escaping () -> Void,
toView targetView: UIView) {
let target: GestureTarget
if let existingTarget = existingTarget(inTargetView: targetView) {
target = existingTarget
} else {
target = GestureTarget()
targetView.addSubview(target)
}
let container = ClosureContainer(closure: closure)
container.gesture = gesture
target.containers.append(container)
gesture.addTarget(target, action: #selector(GestureTarget.target(gesture:)))
targetView.addGestureRecognizer(gesture)
}
class func existingTarget(inTargetView targetView: UIView) -> GestureTarget? {
for subview in targetView.subviews {
if let target = subview as? GestureTarget {
return target
}
}
return nil
}
func cleanUpContainers() {
containers = containers.filter({ $0.gesture != nil })
}
@objc func target(gesture: UIGestureRecognizer) {
cleanUpContainers()
for container in containers {
guard let containerGesture = container.gesture else {
continue
}
if gesture === containerGesture {
container.closure()
}
}
}
}
РЕДАКТИРОВАТЬ 1 :-
Используйте вот так
UIGestureRecognizer.init(addToView: yourView, closure: {
// your code
})
Комментарии:
1. как мы используем это
2. @srikanthkumar взгляните на это.
3. Я использую следующий способ, но он не получает никакого действия let get = UIPanGestureRecognizer(target: self, action: #selector(pangectureRecognizerDismissoneScreen(_:))) UIGestureRecognizer.init(addToView: uiview) { self.view.backgroundColor = UIColor.DarkGray.withAlphaComponent(0.1) self.uiview.addGestureRecognizer(получить) }
4. Вы видите в моем коде, какой бы вид вы ни передали в «addToView», он будет выполнять распознавание жестов, В завершении (закрытии) вы можете выполнить любое действие, если у вас все еще есть сомнения, проверьте эту ссылку gist.github.com/loganwright/3bd5fe87d499eff23d4a @srikanthkumar