Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIPangestureRecognitor不';t触发动作_Ios_Swift_Uiview_Uipangesturerecognizer - Fatal编程技术网

Ios UIPangestureRecognitor不';t触发动作

Ios UIPangestureRecognitor不';t触发动作,ios,swift,uiview,uipangesturerecognizer,Ios,Swift,Uiview,Uipangesturerecognizer,我正在尝试创建UIView的一个子类,以便在视图上进行平移来扩展视图。它应该是这样工作的:如果用户使平移朝向顶部,则视图的高度会降低,而如果平移朝向底部,则视图的高度会增加。为了实现这一功能,我尝试向视图中添加一个UIPangestureRecognitor,但它似乎不起作用。我是这样做的: 第一个片段是uiView子类声明 class ExpandibleView: UIView { //Here I create the reference to the recognizer

我正在尝试创建UIView的一个子类,以便在视图上进行平移来扩展视图。它应该是这样工作的:如果用户使平移朝向顶部,则视图的高度会降低,而如果平移朝向底部,则视图的高度会增加。为了实现这一功能,我尝试向视图中添加一个UIPangestureRecognitor,但它似乎不起作用。我是这样做的:

第一个片段是uiView子类声明

class ExpandibleView: UIView {
    //Here I create the reference to the recognizer
    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))

    //And here I set its minimumNumberOfTouches and maximumNumberOfTouches properties and add it to the view
    func initialize() {
        panGestureRecognizer.minimumNumberOfTouches = 1
        panGestureRecognizer.maximumNumberOfTouches = 1
        self.addGestureRecognizer(panGestureRecognizer)
    }

    //here's the function that should handle the pan but who instead doesn't seem to been called at all
    @objc func handlePan(_ sender:UIPanGestureRecognizer) {
        //Here's I handle the Pan
    }
}
第二个是视图控制器内部的实现

class MapViewController: UIViewController {
    @IBOutlet weak var profileView: ExpandibleView!

    //MARK: - ViewController Delegate Methods

    override func viewDidLoad() {
        super.viewDidLoad()

        //Here I set the View
        profileView.isUserInteractionEnabled = true
        profileView.initialize()
        profileView.minHeight = 100
        profileView.maxHeight = 190
    }

}
我在故事板内部将视图的类设置为我创建的子类,但识别器在所有处理程序中都不会触发。

尝试更改此设置

class ExpandibleView: UIView {

    func initialize() {


    }

    //here's the function that should handle the pan but who instead doesn't seem to been called at all
     func handlePan() {
        //your function
    }
}

class MapViewController: UIViewController {
    @IBOutlet weak var profileView: ExpandibleView!

    //MARK: - ViewController Delegate Methods

    override func viewDidLoad() {
        super.viewDidLoad()
     let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
     panGestureRecognizer.minimumNumberOfTouches = 1
        panGestureRecognizer.maximumNumberOfTouches = 1
     profileView.addGestureRecognizer(panGestureRecognizer)
        //Here I set the View
        profileView.isUserInteractionEnabled = true
        profileView.initialize()
        profileView.minHeight = 100
        profileView.maxHeight = 190
    }

   @objc func handlePan(_ sender:UIPanGestureRecognizer) {
       profileView.handlePan()
    }
}
也可以在其他视图中为调用创建委托

祝你好运

尝试更改此选项

class ExpandibleView: UIView {

    func initialize() {


    }

    //here's the function that should handle the pan but who instead doesn't seem to been called at all
     func handlePan() {
        //your function
    }
}

class MapViewController: UIViewController {
    @IBOutlet weak var profileView: ExpandibleView!

    //MARK: - ViewController Delegate Methods

    override func viewDidLoad() {
        super.viewDidLoad()
     let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
     panGestureRecognizer.minimumNumberOfTouches = 1
        panGestureRecognizer.maximumNumberOfTouches = 1
     profileView.addGestureRecognizer(panGestureRecognizer)
        //Here I set the View
        profileView.isUserInteractionEnabled = true
        profileView.initialize()
        profileView.minHeight = 100
        profileView.maxHeight = 190
    }

   @objc func handlePan(_ sender:UIPanGestureRecognizer) {
       profileView.handlePan()
    }
}
也可以在其他视图中为调用创建委托


祝你好运

您遇到的问题是由于您在此处的类定义中定义了
pangestrerecognizer
变量:

//Here I create the reference to the recognizer
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
您可以用这种方式初始化它,但在创建此变量时似乎没有设置
self
。所以你的行为从未被注册过

有几种方法可以使用代码解决此问题,您可以继续将其初始化为实例变量,但需要在
initialize()
函数中设置目标/操作

let panGestureRecognizer = UIPanGestureRecognizer()

func initialize() {
    // add your target/action here
    panGestureRecognizer.addTarget(self, action: #selector(handlePan(_:)))
    panGestureRecognizer.minimumNumberOfTouches = 1
    panGestureRecognizer.maximumNumberOfTouches = 1
    addGestureRecognizer(panGestureRecognizer)
}
或者,您可以在initialize函数中简单地初始化手势识别器,而不使用实例变量

func initialize() {
    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
    panGestureRecognizer.minimumNumberOfTouches = 1
    panGestureRecognizer.maximumNumberOfTouches = 1
    addGestureRecognizer(panGestureRecognizer)
}
我的原始答案

下面是一个解决方案,它使用在情节提要中定义的视图的约束或直接操纵帧

带有约束的示例

import UIKit

// Delegate protocol for managing constraint updates if needed
protocol MorphDelegate: class {

    // tells the delegate to change its size constraints
    func morph(x: CGFloat, y: CGFloat)
}

class ExpandableView: UIView {

    var delegate: MorphDelegate?

    init() {
        // frame is set later if needed by creator when using this init method
        super.init(frame: CGRect.zero)
        configureGestureRecognizers()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureGestureRecognizers()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        configureGestureRecognizers()
    }

    // setup UIPanGestureRecognizer
    internal func configureGestureRecognizers() {
        let panGR = UIPanGestureRecognizer.init(target: self, action: #selector(didPan(_:)))
        addGestureRecognizer(panGR)
    }

    @objc func didPan(_ panGR: UIPanGestureRecognizer) {

        // get the translation
        let translation = panGR.translation(in: self).applying(transform)

        if let delegate = delegate {

            // tell delegate to change the constraints using this translation
            delegate.morph(x: translation.x, y: translation.y)

        } else {

            // If you want the view to expand/contract in opposite direction
            // of drag then swap the + and - in the 2 lines below
            let newOriginY = frame.origin.y + translation.y
            let newHeight = frame.size.height - translation.y

            // expand self via frame manipulation
            let newFrame = CGRect(x: frame.origin.x, y: newOriginY, width: frame.size.width, height: newHeight)
            frame = newFrame
        }

        // reset translation
        panGR.setTranslation(CGPoint.zero, in: self)
    }

}
如果您想通过在故事板中定义类并操纵它的约束来使用它,您可以这样做

首先在故事板中定义视图,并约束其宽度和高度。对于演示,我将其x位置约束到视图中心,底部约束到SafeArea.bottom

为视图创建IBOutlet,以及视图控制器文件的高度约束

在本例中,我将背景颜色设置为蓝色

在视图控制器中,我定义了一个函数来设置视图(当前仅设置约束操纵回调的委托),然后定义了一个扩展来处理更新约束的委托调用

class ViewController: UIViewController {

    @IBOutlet weak var expandingView: ExpandableView!
    @IBOutlet weak var constraint_expViewHeight: NSLayoutConstraint!


    override func viewDidLoad() {
        super.viewDidLoad()

        // call to configure our expanding view
        configureExpandingView()
    }

    // this sets the delegate for an expanding view defined in the storyboard
    func configureExpandingView() {
        expandingView.delegate = self
    }
}

// setup the delegate callback to handle constraint manipulation
extension ViewController: MorphDelegate {

    func morph(x: CGFloat, y: CGFloat) {

        // this will update the view's height based on the amount
        // you drag your finger in the view. You can '+=' below if
        // you want to reverse the expanding behavior based on pan
        // movements.
        constraint_expViewHeight.constant -= y
    }
}
当我运行项目时,通过约束以这种方式执行此操作会产生以下效果:

帧操作示例

要使用此属性并仅使用“框架”属性操纵高度,视图控制器可能会实现视图创建,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()

    setupExpandingView()
}

func setupExpandingView() {

    let newView = ExpandableView()
    newView.backgroundColor = .red
    newView.frame = CGRect(x: 20, y: 200, width: 100, height: 100)
    view.addSubview(newView)
}
仅使用帧操纵,我得到以下结果:


您遇到的问题是由于您在此处的类定义中定义了
pangestrerecognizer
变量:

//Here I create the reference to the recognizer
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
您可以用这种方式初始化它,但在创建此变量时似乎没有设置
self
。所以你的行为从未被注册过

有几种方法可以使用代码解决此问题,您可以继续将其初始化为实例变量,但需要在
initialize()
函数中设置目标/操作

let panGestureRecognizer = UIPanGestureRecognizer()

func initialize() {
    // add your target/action here
    panGestureRecognizer.addTarget(self, action: #selector(handlePan(_:)))
    panGestureRecognizer.minimumNumberOfTouches = 1
    panGestureRecognizer.maximumNumberOfTouches = 1
    addGestureRecognizer(panGestureRecognizer)
}
或者,您可以在initialize函数中简单地初始化手势识别器,而不使用实例变量

func initialize() {
    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
    panGestureRecognizer.minimumNumberOfTouches = 1
    panGestureRecognizer.maximumNumberOfTouches = 1
    addGestureRecognizer(panGestureRecognizer)
}
我的原始答案

下面是一个解决方案,它使用在情节提要中定义的视图的约束或直接操纵帧

带有约束的示例

import UIKit

// Delegate protocol for managing constraint updates if needed
protocol MorphDelegate: class {

    // tells the delegate to change its size constraints
    func morph(x: CGFloat, y: CGFloat)
}

class ExpandableView: UIView {

    var delegate: MorphDelegate?

    init() {
        // frame is set later if needed by creator when using this init method
        super.init(frame: CGRect.zero)
        configureGestureRecognizers()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureGestureRecognizers()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        configureGestureRecognizers()
    }

    // setup UIPanGestureRecognizer
    internal func configureGestureRecognizers() {
        let panGR = UIPanGestureRecognizer.init(target: self, action: #selector(didPan(_:)))
        addGestureRecognizer(panGR)
    }

    @objc func didPan(_ panGR: UIPanGestureRecognizer) {

        // get the translation
        let translation = panGR.translation(in: self).applying(transform)

        if let delegate = delegate {

            // tell delegate to change the constraints using this translation
            delegate.morph(x: translation.x, y: translation.y)

        } else {

            // If you want the view to expand/contract in opposite direction
            // of drag then swap the + and - in the 2 lines below
            let newOriginY = frame.origin.y + translation.y
            let newHeight = frame.size.height - translation.y

            // expand self via frame manipulation
            let newFrame = CGRect(x: frame.origin.x, y: newOriginY, width: frame.size.width, height: newHeight)
            frame = newFrame
        }

        // reset translation
        panGR.setTranslation(CGPoint.zero, in: self)
    }

}
如果您想通过在故事板中定义类并操纵它的约束来使用它,您可以这样做

首先在故事板中定义视图,并约束其宽度和高度。对于演示,我将其x位置约束到视图中心,底部约束到SafeArea.bottom

为视图创建IBOutlet,以及视图控制器文件的高度约束

在本例中,我将背景颜色设置为蓝色

在视图控制器中,我定义了一个函数来设置视图(当前仅设置约束操纵回调的委托),然后定义了一个扩展来处理更新约束的委托调用

class ViewController: UIViewController {

    @IBOutlet weak var expandingView: ExpandableView!
    @IBOutlet weak var constraint_expViewHeight: NSLayoutConstraint!


    override func viewDidLoad() {
        super.viewDidLoad()

        // call to configure our expanding view
        configureExpandingView()
    }

    // this sets the delegate for an expanding view defined in the storyboard
    func configureExpandingView() {
        expandingView.delegate = self
    }
}

// setup the delegate callback to handle constraint manipulation
extension ViewController: MorphDelegate {

    func morph(x: CGFloat, y: CGFloat) {

        // this will update the view's height based on the amount
        // you drag your finger in the view. You can '+=' below if
        // you want to reverse the expanding behavior based on pan
        // movements.
        constraint_expViewHeight.constant -= y
    }
}
当我运行项目时,通过约束以这种方式执行此操作会产生以下效果:

帧操作示例

要使用此属性并仅使用“框架”属性操纵高度,视图控制器可能会实现视图创建,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()

    setupExpandingView()
}

func setupExpandingView() {

    let newView = ExpandableView()
    newView.backgroundColor = .red
    newView.frame = CGRect(x: 20, y: 200, width: 100, height: 100)
    view.addSubview(newView)
}
仅使用帧操纵,我得到以下结果:


更改参数类型无效。“在其他视图中为调用创建委托”是什么意思?它一直不起作用..我真的不明白错在哪里更改参数类型不起作用。“在其他视图中为调用创建代理”是什么意思?它一直不起作用..我真的不明白这是怎么回事..非常感谢..另一件事。。为了展开视图,我正在更改高度约束的高度,但当我这样做时,视图不会展开。我不确定“我正在更改高度约束高度”是什么意思。。。是否正在更改高度约束
.constant
属性?另外,如果您正在使用演示的委派设置,是否正在设置展开视图的委派属性以确保在视图控制器中调用回调?这很有效..非常感谢..另一件事。。为了展开视图,我正在更改高度约束的高度,但当我这样做时,视图不会展开。我不确定“我正在更改高度约束高度”是什么意思。。。是否正在更改高度约束
.constant
属性?此外,如果您正在使用演示的委派设置,是否正在设置展开视图的de