0

開始というボタンをクリックすると、作成中のボタンが画面の片側から反対側に移動するゲームを作成しています。問題は、移動していたボタンが終点に到達する前に開始をクリックすると、続行せずに停止することです (そして、別の作成されたボタンが期待どおりに移動し始めます)。スタート ボタンをクリックするたびに新しい CADisplayLink を作成する必要がありますか? もしそうなら、どうすればいいですか?コードは次のとおりです。

var button1 = UIButton()
var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 2.0
var leadingConstraint: NSLayoutConstraint!
var topConstraint: NSLayoutConstraint!
var l1 = false
@IBAction func start(sender: UIButton) {
    n1()
}
func n1() {
    l1 = false
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
func handleDisplayLink(displayLink: CADisplayLink) {
    if l1 == false { // so it doesn't randomize leading constraint twice
        button1 = createButton()
        let randomNumber = Int(arc4random_uniform(180) + 30)
        let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
        var percentComplete = CGFloat(elapsed / duration)
        if percentComplete >= 1.0 {
            percentComplete = 1.0
            //   self.button1.removeFromSuperview()
            displayLink.invalidate()
            button1.hidden = true
        }
        leadingConstraint.constant = CGFloat(randomNumber)
        topConstraint.constant = 390 - 350 * percentComplete
        NSLayoutConstraint.activateConstraints([
            leadingConstraint,
            topConstraint,
            button1.widthAnchor.constraintEqualToConstant(75),
            button1.heightAnchor.constraintEqualToConstant(75)
            ])
        l1 = true
    }
    else{
        let elapsed = CFAbsoluteTimeGetCurrent() - startTime!
        var percentComplete = CGFloat(elapsed / duration)
        if percentComplete >= 1.0 {
            percentComplete = 1.0
            displayLink.invalidate()
            button1.hidden = true
        }
        topConstraint.constant = 390 - 350 * percentComplete
        NSLayoutConstraint.activateConstraints([
            leadingConstraint,
            topConstraint,
            button1.widthAnchor.constraintEqualToConstant(75),
            button1.heightAnchor.constraintEqualToConstant(75)
            ])
    }
}
func buttonPressed(sender: UIButton!) {
    button1.hidden = true
    displayLink?.invalidate()
}
func createButton() ->UIButton {
    let button = UIButton()
    button.setImage(UIImage(named: "BlueBall.png")!, forState: UIControlState.Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    leadingConstraint = button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 0)
    topConstraint = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0)
    NSLayoutConstraint.activateConstraints([
        leadingConstraint,
        topConstraint,
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])
    return button
}

助けてください。本当にありがたいです。前もって感謝します。アントン

4

1 に答える 1

0

オーケー アントン O; 説明したように、移動する UIView でのタッチを検出する方法の回答を投稿します。これは、CAAnimation と UIView.animationWith の両方で機能します。

まず、便宜上、CGRect の拡張機能を作成しました。

extension CGRect {
    init(position: CGPoint, size: CGSize) {
        self.origin = CGPoint(x: position.x - (size.width / 2.0), y: position.y - (size.height / 2.0))
        self.size = size
    }
}

次に、ビューを作成して移動する 2 つのメソッドを作成しました。その後、必要に応じてコードを調整できます。(ビューへの参照を保持するために nextView というグローバル変数を保持していますが、もちろん配列に拡張することもできます)

ビューを作成:

private func createView(index: Int) {
        nextView?.removeFromSuperview()

        nextView = UIView()
        nextView?.bounds = CGRect(x: 0, y: 0, width: 60, height: 60)
        nextView?.backgroundColor = UIColor.redColor()
        nextView?.center = CGPoint(x: 30, y: CGRectGetMidY(self.view.bounds))

        if let nextView = nextView {
            view.addSubview(nextView)
        }
    }

ビューを移動:

private func moveView() {
        guard let nextView = nextView else {
            return
        }

        UIView.animateWithDuration(5.0) { () -> Void in
            nextView.center = CGPoint(x: CGRectGetMaxX(self.view.bounds) + 30, y: CGRectGetMidY(self.view.bounds))
        }
    }

タッチを検出:

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        super.touchesEnded(touches, withEvent: event)

        if let touch = touches.first, nextView = nextView {
            let touchRect = CGRect(position: touch.locationInView(self.view), size: CGSize(width: 20, height: 20))

            guard let viewPosition = nextView.layer.presentationLayer()?.position else {
                return
            }

            let viewRect = CGRect(position: viewPosition, size: nextView.bounds.size)

            if CGRectIntersectsRect(touchRect, viewRect) {
                print(" ")
            } else {
                print("")
            }
        }
    }

必要に応じてメソッドを拡張し、いくつかの「パフォーマンス」強化チェックを追加することもできます (ビューが表示されているかどうか、または touchesEnded メソッドですぐにそこに戻るかなど)。

于 2016-01-05T01:27:35.340 に答える