UIButton এর এমন দৃশ্যের ভিতরে যা একটি UITapGestureRecognizer রয়েছে


184

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

আমি কেবলমাত্র এটির টিপ পাওয়ার পরে কেবল ইউআইটিএপপেশারআর সনাক্তকারীকে সরাতে পারি না। কারণ এটির সাহায্যে নতুন দৃশ্যটিও সরানো যেতে পারে। মানে আমি পূর্ণস্ক্রিন ভিডিও নিয়ন্ত্রণের মতো আচরণ চাই

উত্তর:


256

আপনি নিজের কন্ট্রোলার সেট করতে পারেন বা এর প্রতিনিধি হিসাবে (যেটি অঙ্গভঙ্গি শনাক্তকারী তৈরি করে) UITapGestureRecognizer। তারপরে ডেলিগেটে আপনি প্রয়োগ করতে পারেন -gestureRecognizer:shouldReceiveTouch:। আপনার প্রয়োগে আপনি পরীক্ষা করতে পারেন যদি স্পর্শটি আপনার নতুন সাবউউয়ের সাথে সম্পর্কিত হয় এবং যদি তা হয় তবে ইঙ্গিতটি সনাক্তকারীকে এটিকে উপেক্ষা করার নির্দেশ দিন। নিম্নলিখিত মত কিছু:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // test if our control subview is on-screen
    if (self.controlSubview.superview != nil) {
        if ([touch.view isDescendantOfView:self.controlSubview]) {
            // we touched our control surface
            return NO; // ignore the touch
        }
    }
    return YES; // handle the touch
}

আমার শিরোনাম ফাইলে, আমি আমার দৃষ্টিভঙ্গিটি ইউআইজিস্টোররেগনিজার ডিজিলেট বাস্তবায়ন করেছি এবং আমার .mi তে আপনার কোডটি উপরে যুক্ত করেছি। ট্যাপটি কখনও এই পদ্ধতিতে প্রবেশ করে না, এটি সরাসরি আমার হ্যান্ডলারের কাছে যায়। কোন ধারনা?
kmehta

1
@kmehta আপনি সম্ভবত ইউআইজিস্টারআর সনাক্তকারী প্রতিনিধি সম্পত্তি সেট করতে ভুলে গেছেন।
পর্যন্ত

এই উত্তরটি এমন সমস্ত ক্ষেত্রে পরিচালনা করতে সাধারণ করা যেতে পারে যেখানে কোনও আইবিএ জড়িত রয়েছে?
মার্টিন উইকম্যান

@ মার্টিন আইবিএક્શનটি এখানে সংকলন করেছে voidযাতে এটি সনাক্তকরণের জন্য ব্যবহারের জন্য রানটাইমের সময় কোনও তথ্য রাখে না। তবে আপনি যা করতে পারেন তা হল ভিউ হায়ারার্কি আপ করা, পরীক্ষা করা UIControlএবং NOযদি কোনও নিয়ন্ত্রণ খুঁজে পান তবে ফিরে আসা ।
লিলি ব্যালার্ড 3'11

এই জন্য THX, এটি আমাকে সাহায্য করে। যদি আপনার বোতামটি কোনও ইউআইআইমেজভিউতে থাকে তবে নিশ্চিত করুন যে ব্যবহারকারীভিত্তিক চিত্রটি ভিভ-এ-এবলড ইয়েস-এ সেট করা আছে কিনা।
james075

156

কেভিনের ব্যালার্ডের উত্তরের উপর ক্যাসির অনুসরণ অনুসারে:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
        if ([touch.view isKindOfClass:[UIControl class]]) {
            // we touched a button, slider, or other UIControl
            return NO; // ignore the touch
        }
    return YES; // handle the touch
}

এটি মূলত সমস্ত ব্যবহারকারীর ইনপুট ধরণের নিয়ন্ত্রণ যেমন বোতাম, স্লাইডার ইত্যাদির কাজ করে


1
এটি একটি নমনীয় সমাধান যা setCancelsTouchesInView = NOনিয়ন্ত্রণের সাথে মিথস্ক্রিয়াতে ট্যাপ ইশারায় ট্রিগার না করার সাথে সাথে যেতে পারে । তবে আপনি এটি আরও ভালভাবে লিখতে পারেন:return ![touch.view isKindOfClass:[UIControl class]];
গ্রিগ 13

সুইফট 4+ সমাধান: রিটার্ন! (টাচ.ভিউটি ইউআইসিএন্ট্রোল)
নটিসেলার

103

এই উত্তরটি এখানে পেয়েছে: লিঙ্ক

আপনি ব্যবহার করতে পারেন

tapRecognizer.cancelsTouchesInView = NO;

যা সমস্ত ট্যাপগুলি ধরার জন্য একমাত্র ট্যাপ সনাক্তকারীকে বাধা দেয়

আপডেট - মাইকেল এই সম্পত্তিটি বর্ণনা করে ডকুমেন্টেশনের লিঙ্কটির কথা উল্লেখ করেছে: বাতিল করেছে টাচআইচ ভিউ


8
এটি গ্রহণযোগ্য উত্তর আইএমও হওয়া উচিত। এটি প্রতিটি সাবভিউটিকে তার নিজের হাতে ট্যাপটি পরিচালনা করতে দেয় এবং সেই দৃশ্যের প্রতিরোধ করে যা এতে একটি ট্যাব্রেকনাইজার যুক্ত থাকে এবং এটি 'হাইজ্যাকিং' থেকে ট্যাপ করে। যদি আপনি যা করতে চান তেমন কোনও দৃশ্যকে ক্লিকযোগ্য করে তোলা (প্রথমে উত্তরদাতাকে পদত্যাগ করা / পাঠ্যক্ষেত্রের কীবোর্ডটি আড়াল করা ইত্যাদি) যদি কোনও প্রতিনিধি বাস্তবায়নের দরকার হয় না .. দুর্দান্ত!
EEKay

4
এটি অবশ্যই গ্রহণযোগ্য উত্তর হওয়া উচিত। এই উত্তরটি আমাকে অ্যাপল ডকুমেন্টেশনগুলি সঠিকভাবে পড়তে পরিচালিত করেছিল , যা এটিকে স্পষ্ট করে দেয় যে অঙ্গভঙ্গি সনাক্তকারী আপনাকে স্বতঃস্ফীতিগুলি স্বীকৃত ইভেন্টগুলি পেতে বাধা দেবে যদি আপনি এটি না করেন।
মাইকেল ভ্যান ডের ওয়েস্টুইজেন

1
এটি কাজ করত তবে এখন এটি আমার জন্য কাজ করছে না ... কারণ বোতামের নীচে আমার কাছে একটি স্ক্রোলভিউ রয়েছে? উপরের উত্তরের মতো আমাকে প্রতিনিধি বাস্তবায়ন করতে হয়েছিল।
xissburg

7
কিছুটা পরীক্ষা-নিরীক্ষার পরে, আমি লক্ষ্য করেছি যে এটি কেবল তখনই কাজ করবে যদি ভঙ্গি শনাক্তকরণ ধারণকারীর দর্শনটি ইউআইসিএন্ট্রোলের ভাইবোন হয়, এবং দৃশ্যটি ইউআইসিআরন্টোলের পিতা বা মাতা হয় তা যদি তা হয় না।
xissburg

6
ইচ্ছাকৃতভাবে সত্যিই কাজ করছে না ... হ্যাঁ, এটি ইউআইসিএন্ট্রোলটিতে ইভেন্টটি খেতে ট্যাপ শনাক্তকারীকে প্রতিরোধ করবে। তবে এটি এখনও সনাক্তকারী ক্রিয়াটি চালায় যা একই সময়ে ২ টি অ্যাকশন চালায়।
টেক ইয়িন

71

কেভিন বলার্ডের উত্তরের অনুসরণ হিসাবে, আমারও একই সমস্যা ছিল এবং এই কোডটি ব্যবহার করে শেষ করেছি:

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

এটির একই প্রভাব রয়েছে তবে এটি যে কোনও ইউআইবুটনের সাথে যে কোনও দৃশ্যের গভীরতায় কাজ করবে (আমার ইউআইবাটনটি বেশ কয়েকটি দর্শন গভীর ছিল এবং ইউআইজিস্টেকার রিকনগাইজারের প্রতিনিধিটির কোনও রেফারেন্স ছিল না))


6
এখানে একটি শিশ্ন হতে চান না, কিন্তু এটি সত্যিই হ্যাঁ এবং না। দয়া করে কোকো কনভেনশন ব্যবহার করুন। সত্য / মিথ্যা / NULL কোরফাউন্ডেশন-স্তরকের জন্য।
স্টিপেট

আমি যা পড়েছি তা থেকে, হ্যাঁ এবং কোনও কিছুই পাঠযোগ্যতার জন্য তৈরি করা হয়নি। পঠনযোগ্যতা বিষয়গত। এটি পদ্ধতি এবং সম্পত্তির নামকরণের কনভেনশনগুলি থেকে শুরু করে যার বিষয়ে সবাই অত্যধিক উদ্বিগ্ন নয়। যদি আপনি নামকরণের সম্মেলনে কঠোরভাবে অনুসরণ করতে চান তবে হ্যাঁ যে কোনও এনএসডব্লিউয়ের জন্য হ্যাঁ এবং না ব্যবহার করুন। তবে, আমি বলব যে আপনি যদি বিকাশকারীদের জরিপ করেন তবে আপনি মিশ্র মতামত পাবেন যেগুলির মধ্যে কোনটি আরও পাঠযোগ্য able [বোতাম সেটহিডেন: হ্যাঁ]; -অর- [বোতাম সেট হিডেন: সত্য];
পিম্প জুস ম্যাকজোনস

1
আমি অনুমান করি আমি যা বলতে চাইছি তা হ'ল নামকরণের সম্মেলনের ভিত্তি যদি পাঠযোগ্যতা হয় তবে আমি মনে করি এটি অস্বীকার করা কঠিন যে এটি কিছু ক্ষেত্রে বিষয়বস্তু। আপনি যদি বিশুদ্ধবাদী হন তবে আপনি সেই বক্তব্যটি বুঝতে পারবেন না।
পিম্প জুস ম্যাকজোনস

2
এটিকে বিষয়গত বলে মনে হতে পারে তবে কোকো প্রোগ্রামিংয়ের কিছু পরে আপনি কোডের শব্দার্থিকভাবে সঠিক প্রবাহে প্রবেশ করতে পারেন ... "সত্য" এখন অবাস্তব-সি এর কয়েক বছর পরেও সত্যিই ভুল বলে মনে হচ্ছে, কারণ এটি "লুকানো" সাথে খুব একটা মেলে না because আমরা হব.
কেন্ডাল হেলস্টেটার জেলনার

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

10

আইওএস .0.০ এবং তারপরে, ডিফল্ট নিয়ন্ত্রণ ক্রিয়াগুলি ওভারল্যাপিং অঙ্গভঙ্গি শনাক্তকারীর আচরণকে আটকায়। উদাহরণস্বরূপ, একটি বোতামের জন্য ডিফল্ট ক্রিয়াটি একটি একক ট্যাপ। যদি আপনার কাছে একটি বোতামের প্যারেন্ট ভিউয়ের সাথে একক ট্যাপ অঙ্গভঙ্গি সনাক্তকারী সংযুক্ত থাকে এবং ব্যবহারকারী বোতামটি ট্যাপ করে তবে বোতামটির ক্রিয়া পদ্ধতিটি অঙ্গভঙ্গি সনাক্তকারীর পরিবর্তে স্পর্শ ইভেন্টটি গ্রহণ করে। এটি কেবলমাত্র অঙ্গভঙ্গি স্বীকৃতিতে প্রযোজ্য যা কোনও নিয়ন্ত্রণের জন্য ডিফল্ট ক্রিয়াকে ওভারল্যাপ করে, যার মধ্যে রয়েছে: .....

অ্যাপলের এপিআই ডক থেকে


8

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

আপনার * .h ফাইলে এটি যুক্ত করুন

@interface v1ViewController : UIViewController <UIGestureRecognizerDelegate>

আপনার * .m ফাইলে এটি যুক্ত করুন

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    NSLog(@"went here ...");

    if ([touch.view isKindOfClass:[UIControl class]])
    {
        // we touched a button, slider, or other UIControl
        return NO; // ignore the touch
    }
    return YES; // handle the touch
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.



    //tap gestrure
    UITapGestureRecognizer *tapGestRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(screenTappedOnce)];
    [tapGestRecog setNumberOfTapsRequired:1];
    [self.view addGestureRecognizer:tapGestRecog];


// This line is very important. if You don't add it then your boolean operation will never get called
tapGestRecog.delegate = self;

}


-(IBAction) screenTappedOnce
{
    NSLog(@"screenTappedOnce ...");

}

7

এখান থেকে এটি করার আর একটি উপায় খুঁজে পেয়েছি । এটি প্রতিটি বোতামের ভিতরে আছে কিনা তা স্পর্শ সনাক্ত করে।

(1) পয়েন্টআইনসাইড: উইথ এভেন্ট: (2) লোকেশনউইউ ভিউ :

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
       shouldReceiveTouch:(UITouch *)touch {
    // Don't recognize taps in the buttons
    return (![self.button1 pointInside:[touch locationInView:self.button1] withEvent:nil] &&
            ![self.button2 pointInside:[touch locationInView:self.button2] withEvent:nil] &&
            ![self.button3 pointInside:[touch locationInView:self.button3] withEvent:nil]);
}

আমি এর জন্য অন্যান্য সমস্ত সমাধানের চেষ্টা করেছি, তবে দ্য পয়েন্ট-ইনসাইড: উইথ অ্যাভেন্ট: অ্যাপ্রোচই আমার পক্ষে কাজ করেছিল।
কেনি ওয়াইল্যান্ড


3

সুইফট 5

টেপস্টেচার সহ সুপারভিউতে বোতাম

 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if let _ = touch.view as? UIButton { return false }
    return true
}

আমার ক্ষেত্রে হিট টেস্ট প্রয়োগকারী আমার পক্ষে কাজ করেছিল। আমার বোতামের সাথে কালেকশন ভিউ ছিল

point(inside:with:)কোন সাবভিউটি স্পর্শ ইভেন্টটি গ্রহণ করতে হবে তা নির্ধারণ করতে প্রতিটি সাবউভিউয়ের পদ্ধতিতে কল করে এই পদ্ধতিটি ভিউ হায়ারার্কিকে অতিক্রম করে । যদি point(inside:with:)সত্যটি ফিরে আসে, তবে নির্দিষ্ট পয়েন্টযুক্ত সামনেরতম দৃশ্যটি না পাওয়া পর্যন্ত সাবভিউয়ের শ্রেণিবিন্যাস একইভাবে ট্র্যাভারস করা হবে।

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    guard isUserInteractionEnabled else { return nil }

    guard !isHidden else { return nil }

    guard alpha >= 0.01 else { return nil }

    guard self.point(inside: point, with: event) else { return nil }

    for eachImageCell in collectionView.visibleCells {
        for eachImageButton in eachImageCell.subviews {
            if let crossButton = eachImageButton as? UIButton {
                if crossButton.point(inside: convert(point, to: crossButton), with: event) {
                    return crossButton
                }
            }
        }
    }
    return super.hitTest(point, with: event)
}

1

আপনি নীচের বুলিয়ানটি সেট করে অন্যান্য ইভেন্টগুলি (যেমন আপনার বোতামের ট্যাপ) বাতিল করা থেকে ইউআইটিএপপেশারআরগনাইজারকে আটকাতে পারেন:

    [tapRecognizer setCancelsTouchesInView:NO];

1

আপনার পরিস্থিতি যদি এরকম হয়:

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

তারপরে সমাধানটি হ'ল:

আপনার এক্সওয়াইজেভিউউকন্ট্রোল.আরএমে নিম্নলিখিত পদ্ধতিটি যুক্ত করুন (এতে আপনার দৃষ্টিভঙ্গি রয়েছে)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

প্রথমে আমি @ সিড্যাশরের জবাব দিয়ে চেষ্টা করেছি তবে আমার ক্ষেত্রে এমনকি বোতামে ক্লিক করার পরেও আমি আইটেমটি ভিউকন্ট্রোলারে আমার "ভিউ" হিসাবে দেখছি তবে আমার "ইউআইবাটন" নিয়ন্ত্রণ নয়। কেউ কি বলতে পারেন যে স্পর্শের দেখার সম্পত্তিটি কেন সেই মূল দৃশ্যে ফিরে আসছে না যেখানে
ট্যাপটি

1
আপনার যদি কোনও স্ক্রোলভিউ বা স্পর্শ ইভেন্টগুলির দাবি করে এমন অন্য কোনও ভিউ থাকে তবে কাজ করবে না।
lkraider

1

সিডাসারের উত্তর অনুকূলিতকরণ, আপনি পাবেন

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
       shouldReceiveTouch:(UITouch *)touch 
{
    return ![touch.view isKindOfClass:[UIControl class]];
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.