UITapGestureRecognizer সেলফ.ভিউতে আলতো চাপুন তবে সাবভিউগুলি উপেক্ষা করুন


97

আমার এমন একটি বৈশিষ্ট্য বাস্তবায়ন করা দরকার যা আমি স্ব.উভিউতে (দেখুন UIViewCotroller) ডাবল আলতো চাপলে কিছু কোড আনব । তবে এই ভিউটিতে আমার অন্যান্য ইউআই অবজেক্টটি রয়েছে এবং আমি সেগুলির সাথে কোনও সনাক্তকারী বস্তু সংযুক্ত করতে চাই না। আমার দৃষ্টিভঙ্গিতে কীভাবে অঙ্গভঙ্গি করা যায় তার নীচে আমি এই পদ্ধতিটি পেয়েছি এবং আমি জানি এটি কীভাবে কাজ করে। এই মুহূর্তে আমি এই প্রতিবেদককে উপস্থাপনা উপেক্ষা করে তৈরি করার জন্য কোন উপায়টি বেছে নেওয়ার জন্য প্রতিবন্ধীদের সামনে আছি। কোন ধারনা? ধন্যবাদ

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:doubleTap];

4
আমি নিশ্চিত নই, তবে আপনি কি সনাক্তকারীকে বাতিল করার জন্য টাচসইনভিউ সেট করার চেষ্টা করেছেন? সুতরাং [ডাবলট্যাপ সেটকেনসেলস টাচসইনভিউ: না];
জেডিএক্স

উত্তর:


147

UIGestureRecognizerDelegateআপনার selfঅবজেক্টের অভ্যন্তরে প্রোটোকল গ্রহণ করা উচিত এবং ভিউটি পরীক্ষা করার জন্য নীচের পদ্ধতিটি কল করুন। এই পদ্ধতির অভ্যন্তরে আপনার দৃষ্টিভঙ্গিটি পরীক্ষা touch.viewকরে উপযুক্ত বুলটি (হ্যাঁ / না) ফিরিয়ে দিন। এটার মতো কিছু:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([touch.view isDescendantOfView:yourSubView]) {
        return NO;
    }
    return YES;
}

সম্পাদনা: দয়া করে, @ আয়ানের উত্তরও দেখুন!

সুইফট 5

// MARK: UIGestureRecognizerDelegate methods, You need to set the delegate of the recognizer
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
     if touch.view?.isDescendant(of: tableView) == true {
        return false
     }
     return true
}

আরও একটি প্রশ্ন আমার ভিউতে কয়েকটি বোতাম রয়েছে যা কাজ করতে হবে। আমি কীভাবে তাদের জন্য কিছু অগ্রাধিকার নির্ধারণ করতে পারি?
মাতরোসভ আলেকজান্ডার

যদি আপনার বোতামগুলির নিজস্ব অঙ্গভঙ্গি সনাক্তকারী (সম্ভবত) থাকে তবে তাদের অভ্যন্তরগুলি খনন করুন এবং সেগুলি দখল করুন এবং -[UIGestureRecognizer requireGestureRecognizerToFail:]এতে ডকসগুলি পড়তে পারেন তবে এটি তাদের পরিবর্তন না করেই কাজ করতে পারে
bshirley

ঘন্টার পর ঘন্টা এটি খুঁজছিল! ধন্যবাদ! ;)
মাস্টাররাজার

যদি আপনার ifপরীক্ষা ব্যর্থ হয়, আপনার বাস্তবায়ন একটি BOOL ফেরত দিতে ব্যর্থ হয়; যথাযথ শৈলীর জন্য হ্যাঁ, যদি একটি ব্লক (ব্যবহার { }) বা একটি elseশাখায় ফিরে আসে। ধন্যবাদ, যদিও আমাকে কিছুটা পড়তে বাঁচিয়েছে।
রবপি

4
একটি দৃষ্টিভঙ্গি নিজের বংশধর তাই এটি কাজ করে না ... (সামগ্রিক পদ্ধতি ঠিক আছে, অন্য উত্তর দেখুন)
আইএক্সএক্স

109

আর একটি পদ্ধতির সাথে তুলনা করা যদি স্পর্শের দৃষ্টিভঙ্গিটি অঙ্গভঙ্গি দর্শন হয় তবে বংশধররা শর্তটি পাস করবে না। একটি দুর্দান্ত, সাধারণ এক-লাইনার:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return touch.view == gestureRecognizer.view
}

4
গ্রহণযোগ্য উত্তরের চেয়ে এটি আমার পক্ষে আরও ভাল কাজ করছে। আরও অনেক সংক্ষিপ্ত।
সুমন রায়

4
@ ভিউটিতে আলতো চাপার সময় এই পদ্ধতিটি চালু করা হয় না।
প্রবুরজ

4
দুর্দান্ত সংক্ষিপ্ত উত্তর!
স্কুরিওনি

গৃহীত উত্তরটিও কাজ করে না তবে এটি আমার পক্ষে নির্দোষভাবে কাজ করেছিল।
শালিন শাহ

@ প্রব্বু সম্ভবতঃ অঙ্গভঙ্গি শনাক্তকারী এর প্রতিনিধি আগে সেট করা উচিত
কুব্বা

23

এবং সুইফ্ট বৈকল্পিকের জন্য:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if touch.view.isDescendantOfView(yourSubView){
        return false
    }
    return true
}

জেনে রাখা ভাল, প্রাপক কোনও প্রদত্ত দর্শনর সংক্ষিপ্তসার বা সেই দৃশ্যের সমতুল্য কিনা তা নির্দেশ করে এমন isDescendantOfViewএকটি Booleanমান দেয়।


4
আপনার ক্লাসে ইউআইজিস্টাররনগাইনাইজারডেলিগেট সেট করতে ভুলবেন না!
ফক্স5150

4
পরিবর্তে যদি বিবৃতি না করে, আপনি কি কেবল এটি ফিরিয়ে দিতে পারবেন না? ! আগমন (এর: gestureRecognizer.view) touch.view.isDescendant এছাড়াও, দ্রুতগতি 3 ^^ নতুন সিনট্যাক্স
EdwardSanchez

13

সুইফ্ট 5 এবং আইওএস 12 এর UIGestureRecognizerDelegateসাথে একটি পদ্ধতি বলা হয় gestureRecognizer(_:shouldReceive:)gestureRecognizer(_:shouldReceive:)নিম্নলিখিত ঘোষণা আছে:

কোনও অঙ্গভঙ্গি শনাক্তকারী কোনও স্পর্শ উপস্থাপন করে এমন কোনও সামগ্রী গ্রহণ করা উচিত কিনা তা প্রতিনিধিটিকে জিজ্ঞাসা করুন।

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool

নীচের সম্পূর্ণ কোডটি এর সম্ভাব্য বাস্তবায়ন দেখায় gestureRecognizer(_:shouldReceive:)। এই কোড ViewControllerসহ, এর দর্শন (সহ imageView) একটি সংক্ষিপ্তসার একটি ট্যাপ printHello(_:)পদ্ধতিটি ট্রিগার করবে না ।

import UIKit

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(printHello))
        tapGestureRecognizer.delegate = self
        view.addGestureRecognizer(tapGestureRecognizer)

        let imageView = UIImageView(image: UIImage(named: "icon")!)
        imageView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
        view.addSubview(imageView)

        // ⚠️ Enable user interaction for imageView so that it can participate to touch events.
        // Otherwise, taps on imageView will be forwarded to its superview and managed by it.
        imageView.isUserInteractionEnabled = true
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        // Prevent subviews of a specific view to send touch events to the view's gesture recognizers.
        if let touchedView = touch.view, let gestureView = gestureRecognizer.view, touchedView.isDescendant(of: gestureView), touchedView !== gestureView {
            return false
        }
        return true
    }

    @objc func printHello(_ sender: UITapGestureRecognizer) {
        print("Hello")
    }

}

এর বিকল্প বাস্তবায়ন gestureRecognizer(_:shouldReceive:)হতে পারে:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return gestureRecognizer.view === touch.view
}

উল্লেখ্য তবে যে যদি এই বিকল্প কোডটি চেক না touch.viewএকটি subview হয় gestureRecognizer.view


10

সম্পূর্ণ দ্রুত সমাধান (প্রতিনিধি কার্যকর করতে হবে এবং সনাক্তকারী (গুলি) এর জন্য সেট করতে হবে):

class MyViewController: UIViewController UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onBaseTapOnly))
        doubleTapRecognizer.numberOfTapsRequired = 2
        doubleTapRecognizer.delegate = self
        self.view.addGestureRecognizer(doubleTapRecognizer)
    }

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        if touch.view.isDescendantOfView(self.view){
            return false
        }
        return true
    }

    func onBaseTapOnly(sender: UITapGestureRecognizer) {
        if sender.state == .Ended {
            //react to tap
        }
    }
}

6

আপনার স্পর্শ করা সিজিপিয়েন্ট ব্যবহার করে বৈকল্পিক (SWIFT 4.0)

class MyViewController: UIViewController, UIGestureRecognizerDelegate {

  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {

// Get the location in CGPoint
    let location = touch.location(in: nil)

// Check if location is inside the view to avoid
    if viewToAvoid.frame.contains(location) {
        return false
    }

    return true
  }
}

4

সাফ সুইট ওয়ে

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return touch.view == self.view
}

আইওএস 13 এ কখনই কল করা হবে না, কমপক্ষে সোয়াইপজেচারআর সনাক্তকারী দিয়ে।
চেভি দ্য চোরকি

ইয়ান এর উত্তরের সাথে এটি কীভাবে আলাদা?
মিষ্টিফা

3

নোট করুন যে অঙ্গভঙ্গি সনাক্তকারী API এতে পরিবর্তিত হয়েছে:

অঙ্গভঙ্গি সনাক্তকারী (_: উচিত রিসিভ :)

প্রথম প্যারামিটারের বাহ্যিক লেবেলের জন্য আন্ডারস্কোর (এড়িয়ে যাওয়া) সূচকটির বিশেষ নোট নিন।

উপরোক্ত কয়েকটি উদাহরণ ব্যবহার করে, আমি ইভেন্টটি পাচ্ছিলাম না। নীচে একটি উদাহরণ যা সুইফ্ট (3+) এর বর্তমান সংস্করণগুলির জন্য কাজ করে।

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    var shouldReceive = false
    if let clickedView = touch.view {
        if clickedView == self.view {
            shouldReceive = true;
        }
    }
    return shouldReceive
}

2

উপরের সমাধানগুলি প্লাস করুন User Interaction Enabled, আপনার সাব-ভিউ যাচাই করতে ভুলবেন না ।

enter image description here


2

আমাকে সন্তানের দৃশ্যে ইশারাটি আটকাতে হয়েছিল। কেবলমাত্র কাজটিই হ'ল প্রথম দর্শনের অনুমতি দেওয়া এবং রাখা এবং পরবর্তী সমস্ত দর্শনগুলিতে অঙ্গভঙ্গি প্রতিরোধ করা:

   var gestureView: UIView? = nil

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if (gestureView == nil || gestureView == touch.view){
            gestureView = touch.view
            return true
        }
        return false
     }

1

সুইফট 4:

touch.view @ আনটোইনের উত্তরের উপর ভিত্তি করে এখন এটি একটি alচ্ছিক:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if let touchedView = touch.view, touchedView.isDescendant(of: deductibleBackgroundView) {
        return false
    }
    return true
}

0

আপনি আপনার 'দুইবার আলতো চাপুন recogniser' আপনার বোতাম এবং / অথবা অন্যান্য নিয়ন্ত্রণগুলি সঙ্গে সংঘাতে না চান, আপনি সেট করতে পারেন selfযেমন UIGestureRecognizerDelegateএবং বাস্তবায়ন:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
{
    return !(touch.view is UIControl)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.