在UIPanGestureRecognizer处理程序期间动态更新UIButton帧

时间:2015-08-18 04:04:36

标签: ios swift uitableview uibutton uipangesturerecognizer

在我的UIPanGestureRecognizer处理程序中,我试图让我的UIButton更改它的宽度,以便它总是填充左侧或右侧拉出的单元留下的空白。

在我的if gesture.state == .Changed分支机构中,我正在执行以下操作:

let translation = gesture.translationInView(self)
let width = 75 + fabs(translation.x)
self.MarkAsDoneBtn.frame = CGRect(x: self.bounds.size.width, y: 0, width: width, height: 75)

(请原谅神奇的数字)

然而,即使println(self.MarkAsDoneBtn.frame)显示宽度调整,按钮的宽度也不会(视觉上)更新。

是否需要额外的东西来强制按钮采用新的帧尺寸?我还尝试更新self.MarkAsDoneBtn.boundsself.MarkAsDoneBtn.layer.frameself.MarkAsDoneBtn.layer.bounds并致电...

self.MarkAsDoneBtn.setNeedsDisplay()
self.MarkAsDoneBtn.setNeedsLayout()
self.MarkAsDoneBtn.setNeedsUpdateConstraints()

......没有运气。

在下面的示例中,绿色箭头表示用户滑动表格单元格的方向,蓝色按钮右侧的红色区域是我尝试通过更改按钮宽度动态填充的区域。

Screen shot

删除了课程概述:

import UIKit

class ChoreItemTableViewCell: UITableViewCell {
    var MarkAsDoneBtn: UIButton!
    var DeleteLabel: UIButton!
    var originalCenter = CGPoint()

    override func awakeFromNib() {
        super.awakeFromNib()

        let panGesture = UIPanGestureRecognizer(target: self, action: "handlePan:")
        panGesture.delegate = self
        addGestureRecognizer(panGesture)

        self.MarkAsDoneBtn = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
        self.MarkAsDoneBtn.userInteractionEnabled = true
        self.MarkAsDoneBtn.backgroundColor = ColorHelper.instance.getColor("blue")
        self.MarkAsDoneBtn.setImage(UIImage(named: "tick"), forState: .Normal)
        self.MarkAsDoneBtn.contentMode = UIViewContentMode.Redraw

        self.addSubview(self.MarkAsDoneBtn)
    }

    override func layoutSubviews() {
        self.MarkAsDoneBtn.frame = CGRect(x: self.bounds.size.width, y: 0, width: 75, height: 75)
    }

    func handlePan(gesture: UIPanGestureRecognizer) {
        if gesture.state == .Began {
            self.originalCenter = center
        }

        if gesture.state == .Changed {
            let translation = gesture.translationInView(self)
            center = CGPointMake(self.originalCenter.x + translation.x, self.originalCenter.y)

            let width = 75 + fabs(translation.x)
            self.MarkAsDoneBtn.frame = CGRect(x: self.bounds.size.width, y: 0, width: width, height: 75)
        }

        if gesture.state == .Ended {
            let originalFrame = CGRect(x: 0, y: frame.origin.y, width: bounds.size.width, height: bounds.size.height)
            UIView.animateWithDuration(0.2, animations: { self.frame = originalFrame })
        }
    }
}

1 个答案:

答案 0 :(得分:0)

每次移动UIView(以任何方式调整frame属性)时,都会认为需要布局。所以调用它的方法layoutSubviews()

您的ChoreItemTableViewCell内置了滑动识别功能。它通过相对于tableView移动整个帧来响应滑动,这会导致其layoutSubviews()被调用。 (把print()放在那里!)这在handlePan()中不太方便地撤消你的计算。更根本的是,你违反了分工。您的handlePan()只应记录翻译状态。然后layoutSubviews() 使用翻译状态重新计算子视图框架。