web-dev-qa-db-ja.com

Interface Builderを使用してUIScreenEdgePanGestureRecognizerを設定するにはどうすればよいですか?

Interface Builderを使用してビューコントローラーに追加すると、作成時にUIScreenEdgePanGestureRecognizerを機能させることができないため、ここで問題が発生しているかどうか、またはバグがあるかどうかを確認します。 Xcode。

再現する手順は次のとおりです。

  • IOSの「シングルビューアプリケーション」テンプレートを使用して、新しいXcodeプロジェクトを作成します。
  • インターフェースビルダーのオブジェクトライブラリからUIViewをメインビューコントローラーにドラッグして追加します。
  • UIScreenEdgePanGestureRecognizerをビューに追加するには、インターフェイスビルダーのオブジェクトライブラリからビューをドラッグします。
  • ジェスチャー認識機能が有効になっていて、エッジが選択されていることを確認します。

enter image description here

  • ViewControllerクラスのアシスタントエディターを開き、ctrlキーを押しながらUIScreenEdgePanGestureRecognizerからViewControllerの実装ブロックにドラッグして、新しいIBAction `にブレークポイントを追加しますEdgeパンジェスチャーが認識されているかどうかをテストするアクションのメソッド本体

結果のコードは次のとおりです。

Code example

デバイス(iOS 8.02を実行しているiPhone 6)でアプリケーションを実行すると、エッジスワイプを実行してもブレークポイントにヒットしません。

行方不明のものはありますか?

更新:これはバグとして08-Oct-2014にApple(rdar:// 18582306)で報告されましたが、Xcode 6.4ではまだ解決されていません) (6E35b)

20
j b

私はあなたの質問をテストするプロジェクトを設定しましたが、あなたがした同じ問題を見つけました。テスト用に設定したシナリオは次のとおりです。

  • インターフェイスビルダーを使用して、画面のエッジジェスチャーを構築するのとまったく同じように行いました。私のコードの唯一の違いは、セレクターにコード行を置いたので、デバッガーは停止する必要があるでしょう。デバッガーは、検出したとおりに停止できませんでした。

    -(void)handlePan:(id)sender
    {
        NSString *test = @"";
    }
    
  • 次に、インターフェイスビルダーを使用して同じビューでピンチジェスチャーを使用して追加のジェスチャーを作成し、そのセレクター内でデバッガーを停止させることができました。したがって、Interface Builderは他のジェスチャーを正しく構築できるようです。

  • 次に、次のコードを使用して画面のエッジジェスチャを手動で作成しましたが、期待どおりに機能しました。

ViewController.hファイルには、UIGestureRecognizerDelegateを含めました。

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
@end

ViewController.mファイルでは、ジェスチャーを手動で実装しました。

#import "ViewController.h"

@interface ViewController ()

-(void)handlePan:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];
    UIScreenEdgePanGestureRecognizer *pan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
                                                                                              action:@selector(handlePan:)];
    [pan setEdges:UIRectEdgeLeft];
    [pan setDelegate:self];
    [self.view addGestureRecognizer:pan];
}

-(void)handlePan:(id)sender
{
    NSString *test = @"";
}

@end

私はあなたがしたのと同じ結論に終わりました-UIScreenEdgePanGestureRecognizerのInterface Builderの実装に何か問題があるようです。

24
sunergeos

Xcode 7.0 Beta 4(7A165t)で試しましたが、まだバグです。 Interface Builderを介してScreen Edge Pan Gesture Recognizerを追加しても、参照されたIBActionは呼び出されませんが、プログラムで次のように追加すると正常に機能します。

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let edgeGestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "userSwipedFromEdge:")
        edgeGestureRecognizer.edges = UIRectEdge.Left
        edgeGestureRecognizer.delegate = self
        self.view.addGestureRecognizer(edgeGestureRecognizer)
    }

    func userSwipedFromEdge(sender: UIScreenEdgePanGestureRecognizer) {
        if sender.edges == UIRectEdge.Left {
            print("It works!")
        }
    }
}

ヒント:UIGestureRecognizerDelegateプロトコルをクラスに追加することを忘れないでください。そうしないと、edgeGestureRecognizer.delegate = selfでエラーが発生します

8
Peter

これはバグと考えることができますが、実際には次のようなものがあります。

「画面のエッジパンジェスチャーレコグナイザーを作成した後、ジェスチャーレコグナイザーをビューにアタッチする前に、適切な値をエッジプロパティに割り当てます。」

https://developer.Apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIScreenEdgePanGestureRecognizer_class/index.html

この要件はUIScreenEdgePanGestureRecognizerにのみ適用されるので、Xcodeが間違っているのはそのためだと思います。通常のシーケンスalloc-> init-> attach-> set値として実装する必要があります。他のすべてのGestureRecongnizerで機能しますが、UIScreenEdgePanGestureRecognizerでは機能しません。

6
Thomas LIU

Xcodeは常に良い隣人というわけではありません。ごめんなさい。

override func viewDidLoad() {
    super.viewDidLoad()

    let panGesture = UIScreenEdgePanGestureRecognizer(target: self, action: "panAction:")
    panGesture.edges = .Left
    view.addGestureRecognizer(panGesture)
}


func panAction(sender: UIScreenEdgePanGestureRecognizer) {
    let translation = sender.translationInView(sender.view!)

    println("Trans:\(translation)")
}
3
Zelko

Xcode 6.4のインターフェースビルダーとSwiftにバグがあるようです。また、Thomas LIUの答えも正解でした。Edgeプロパティは、Interface Builderではなくコードで設定する必要があるようです。

IBにはEdgeチェックボックスがありますが、無視されているようです。

私はこのように解決しました。ジェスチャーレコグナイザーからCtrlキーを押しながらビューコントローラークラスにドラッグして、IBOutletを作成します。

class ViewController: UIViewController {
    @IBOutlet var leftEdgeGestureRecognizer: UIScreenEdgePanGestureRecognizer!

次に、viewDidLoadで:

leftEdgeGestureRecognizer.edges = .Left

最後に、認識機能からCtrlキーを押しながらドラッグして、IBActionを作成します。

@IBAction func swipeFromLeft(sender: AnyObject) {
        print("===> Swipe from left Edge.\n")
}
2
drtofu

複数のジェスチャーレコグナイザーが連携して機能できるようにするには、メソッドshouldRecognizeSimultaneouslyWithGestureRecognizerを実装してtrueを返す必要があります。

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Swiftコードについては申し訳ありませんが、アイデアを理解する必要があります。

ビューはMKMapViewなどの独自の(システム)認識機能を持つことができるため、単一のジェスチャー認識機能を使用している場合でも、このメソッドを実装する必要があります。

2
zisoft

長い間同じ問題に直面しています。そのxcodeバグは、プログラムで追加することをお勧めします。

1
itsji10dra