অন্য ইউআইভিউয়ের অধীনে একটি ইউআইভিউয়ের সাথে কথোপকথনের মঞ্জুরি দেওয়া হচ্ছে


115

অন্য ইউআইভিউয়ের অধীনে থাকা কোনও ইউআইভিউতে একটি বোতামের সাথে কথোপকথনের অনুমতি দেওয়ার কি কোনও সহজ উপায় আছে - যেখানে বোতামের শীর্ষে শীর্ষে ইউআইভিউ থেকে কোনও আসল অবজেক্ট নেই?

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

আমি বিতে বোতামগুলি দেখতে পাচ্ছি - আমি এ এর ​​ব্যাকগ্রাউন্ডটি ক্লিয়ারার কালারে সেট করে দিয়েছি - তবে বি এর বোতামগুলি স্পর্শ পেয়েছে বলে মনে হচ্ছে না যে এগুলির বোতামগুলির উপরে আসলে কোনও বস্তু নেই।

সম্পাদনা করুন - আমি এখনও শীর্ষ ইউআইভিউতে অবজেক্টগুলির সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হতে চাই

অবশ্যই এটি করার একটি সহজ উপায় আছে?


2
এটি বেশিরভাগ ক্ষেত্রে এখানে ব্যাখ্যা করা হয়েছে: বিকাশকারী.এপল / আইফোন / লাইবারি / ডকুমেন্টেশন / আইফোন / But তবে মূলত, হিটটেষ্টকে ওভাররাইড করে: ইভেন্ট: সহ, তারা একটি কোডের নমুনা সরবরাহ করে।
ন্যাশ

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

উত্তর:


97

আপনার শীর্ষ দর্শনের জন্য আপনার একটি ইউআইভিউ সাবক্লাস তৈরি করা উচিত এবং নিম্নলিখিত পদ্ধতিটি ওভাররাইড করুন:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // UIView will be "transparent" for touch events if we return NO
    return (point.y < MIDDLE_Y1 || point.y > MIDDLE_Y2);
}

আপনি হিট টেস্ট: ইভেন্ট: পদ্ধতিটিও দেখতে পারেন।


19
এখানে মিডল_ওয়াই 1 / ওয়াই 2 কী উপস্থাপন করছে?
জেসন রেনালদো

এই returnবিবৃতিটি কী করছে তা নিশ্চিত নয় , তবে return CGRectContainsPoint(eachSubview.frame, point)আমার পক্ষে কাজ করে। অন্যথায়
চূড়ান্ত

MIDDLE_Y1 / Y2 ব্যবসা কেবল একটি উদাহরণ। এই MIDDLE_Y1<=y<=MIDDLE_Y2অঞ্চলে স্পর্শ ইভেন্টের জন্য এই ফাংশনটি "স্বচ্ছ" হবে ।
gyim

41

যদিও এখানে বেশিরভাগ উত্তর কাজ করবে, আমি একটু অবাক হয়ে দেখলাম যে এখানে সবচেয়ে সুবিধাজনক, জেনেরিক এবং বোকা উত্তর দেওয়া হয়নি। @ আশ কাছাকাছি এসেছিল, তদারকি করা ফিরিয়ে দেওয়ার ক্ষেত্রে অদ্ভুত কিছু ঘটছে ... তা করবেন না।

এই উত্তরটি এখানে একটি অনুরূপ প্রশ্নের আমি যে উত্তর দিয়েছি তা থেকে নেওয়া হয়েছে

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self) return nil;
    return hitView;
}

[super hitTest:point withEvent:event]স্পর্শ করা হয়েছে যে ভিউ এর শ্রেণিবিন্যাসের গভীরতম দৃশ্য ফিরে আসবে। যদি hitView == self(অর্থাত যদি টাচ পয়েন্ট অধীনে কোন subview হয়), এর বিনিময়ে nil, উল্লেখ যে এই দৃশ্য উচিত না স্পর্শ পাই। প্রতিক্রিয়াশীল চেইন যেভাবে কাজ করে তার অর্থ হল যে এই বিন্দুর উপরে ভিউয়ের শ্রেণিবিন্যাস ট্র্যাশ করা অব্যাহত থাকবে যতক্ষণ না কোনও ভিউ পাওয়া যায় যা স্পর্শে সাড়া দেয়। সুপারভিউটি ফিরিয়ে দেবেন না , কারণ এটির মতামত এই নয় যে এর তত্ত্বাবধানটি ছোঁয়া গ্রহণ করবে কিনা!

এই সমাধানটি হ'ল:

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

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

@interface ISView : UIView
@property(nonatomic, assign) BOOL onlyRespondToTouchesInSubviews;
@end

@implementation ISView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self && onlyRespondToTouchesInSubviews) return nil;
    return hitView;
}
@end

তারপরে বন্য হয়ে যান এবং এই দৃশ্যটি যেখানেই আপনি প্লেইন ব্যবহার করতে পারেন তা ব্যবহার করুন UIView। এটির কনফিগারেশন সেট onlyRespondToTouchesInSubviewsকরার মতোই সহজ YES


2
একমাত্র সঠিক উত্তর। স্পষ্টত, আপনি যদি কোনও দৃশ্যের ছোঁয়াটিকে অগ্রাহ্য করতে চান তবে দৃশ্যের মধ্যে থাকা কোনও বোতাম (বলুন) না, স্টুয়ার্টের ব্যাখ্যা অনুসারে করুন do (আমি সাধারণত এটিকে "ধারক দর্শন" বলি কারণ এটি নির্বিঘ্নে কিছু বোতাম "ধরে" রাখতে পারে তবে, এটি
ধারকটির

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

31

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

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInB = [B convertPoint:point fromView:self];

    if ([B pointInside:pointInB withEvent:event])
        return B;

    return [super hitTest:point withEvent:event];
}

pointInside:withEvent:গিমের পরামর্শ অনুসারে আপনি পদ্ধতিটিও পরিবর্তন করতে পারেন । এটি আপনাকে কমপক্ষে স্পর্শের জন্য কার্যকরভাবে "ছিদ্র করা" এর মাধ্যমে একই ফলাফল অর্জন করতে দেয়।

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([self shouldForwardTouches:touches]) {
        [B touchesBegan:touches withEvent:event];
    }
    else {
        // Do whatever A does with touches.
    }
}

তবে এটি আপনার প্রত্যাশার মতো সবসময় কাজ করে না! মূল জিনিসটি হ'ল ইউআইবাটনের মতো অন্তর্নির্মিত নিয়ন্ত্রণগুলি সর্বদা ফরোয়ার্ড স্পর্শগুলিকে উপেক্ষা করবে। এই কারণে, প্রথম পদ্ধতির আরও নির্ভরযোগ্য।

একটি ভাল ব্লগ পোস্ট এখানে এই সমস্ত ধারণা বিশদ ব্যাখ্যা করার সাথে সাথে একটি ছোট ওয়ার্কিং এক্সকোড প্রকল্প সহ ধারণাগুলি ডেমো করতে এখানে উপলব্ধ:

http://bynomial.com/blog/?p=74


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

@ ডেলাণী, এটি সত্য নয়; আপনি অন্যান্য মতামতের নীচে বসে স্ক্রোলযোগ্য মতামত রাখতে পারেন এবং হিটটেষ্টকে ওভাররাইড করে উভয়কেই কাজ করতে দেন। এখানে কিছু নমুনা কোড রয়েছে: bynomial.com/blogfiles/Temp32.zip
টাইলার

আরে। সমস্ত স্ক্রোলযোগ্য দর্শন নয় - কেবল কয়েকটি ... আমি উপরে থেকে আপনার জিপ কোডটি চেষ্টা করে ইউআইস্ক্রোলভিউকে একটি (উদাহরণস্বরূপ) এমকেম্যাপভিউতে পরিবর্তন করেছি এবং এটি কার্যকর হয় না। ট্যাপস কাজ করে - এটি স্ক্রোলিং যা এটি মনে হচ্ছে।
delany

ঠিক আছে, আমি এটি পরীক্ষা করে দেখেছি এবং নিশ্চিত করেছি যে হিটটেষ্ট এমকেম্যাপভিউয়ের সাথে আপনার পছন্দ মতো কাজ করে না। আপনি ঠিক সে সম্পর্কেই বলেছিলেন, @ ডেলানি; যদিও এটি ইউআইএসক্রোলভিউসের সাথে সঠিকভাবে কাজ করে। আমি ভাবছি কেন এম কে ম্যাপভিউ ব্যর্থ?
টাইলার

@ টাইলার যেমনটি আপনি উল্লেখ করেছেন যে, "মূল বিষয়টি হ'ল ইউআইবাটনের মতো অন্তর্নির্মিত নিয়ন্ত্রণগুলি সর্বদা ফরোয়ার্ড স্পর্শগুলিকে অগ্রাহ্য করবে", আমি জানতে চাই আপনি কীভাবে এটি জানেন এবং এই আচরণের ব্যাখ্যা দেওয়ার জন্য এটি কোনও অফিসিয়াল দলিল কিনা। আমি একটি সমস্যার মুখোমুখি হয়েছিলাম যে যখন ইউআইবাটনটির একটি সরল ইউআইভিউ সাবউভিউ থাকে, তখন এটি সংক্ষিপ্তসারের সীমানায় থাকা ইভেন্টগুলিকে স্পর্শ করবে না। এবং আমি দেখতে পেলাম যে ইভেন্টটি ইউআইভিউটের ডিফল্ট আচরণ হিসাবে যথাযথভাবে ইউআইবাটনকে ফরোয়ার্ড করা হয়েছে, তবে আমি নিশ্চিত নই যে এটি কোনও মনোনীত বৈশিষ্ট্য বা কেবল একটি বাগ g আপনি কি আমাকে এই সম্পর্কে ডকুমেন্টেশন দেখাতে পারেন? আন্তরিকভাবে আপনাকে অনেক ধন্যবাদ।
নিল.মারলিন

29

আপনাকে সেট করতে হবে upperView.userInteractionEnabled = NO;, অন্যথায় উপরের দৃশ্যটি স্পর্শগুলিকে বিরত করবে।

এর ইন্টারফেস বিল্ডার সংস্করণটি "ব্যবহারকারীর ইন্টারঅ্যাকশন সক্ষম করা" নামে পরিচিতি বৈশিষ্ট্য প্যানেলের নীচে একটি চেকবক্স। এটি পরীক্ষা করুন এবং আপনার যাওয়া ভাল হবে should


দুঃখিত - বলা উচিত ছিল। আমি এখনও শীর্ষ ইউআইভিউতে অবজেক্টগুলির সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হতে চাই।
ডেলানী

তবে ওপারভিউ কোনও স্পর্শ পেতে পারে না, উপরের ভিউতে বোতামটি অন্তর্ভুক্ত করে।
imcaptor

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

11

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

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return (CGRectContainsPoint(disclosureButton.frame, point));
}

8

ইদানীং আমি একটি ক্লাস লিখেছিলাম যা আমাকে ঠিক তা করতে সহায়তা করবে। এটির জন্য কাস্টম শ্রেণি হিসাবে ব্যবহার করা UIButtonবা UIViewস্বচ্ছ পিক্সেলের উপর চালিত স্পর্শ ইভেন্টগুলি পাস করবে।

এই সমাধানটি গৃহীত উত্তরের চেয়ে কিছুটা ভাল কারণ আপনি এখনও UIButtonএকটি অর্ধ স্বচ্ছের অধীনে থাকা একটিতে ক্লিক করতে পারেন UIViewযখন স্বচ্ছতার স্বচ্ছ অংশটি UIViewএখনও স্পর্শ ইভেন্টগুলিতে প্রতিক্রিয়া জানাবে।

জিআইএফ

আপনি জিআইএফ-তে দেখতে পাচ্ছেন, জিরাফ বোতামটি একটি সাধারণ আয়তক্ষেত্র তবে স্বচ্ছ অঞ্চলে স্পর্শ ইভেন্টগুলি UIButtonনীচে হলুদে প্রেরণ করা হয় ।

ক্লাসে লিঙ্ক


2
যেহেতু আপনার কোডটি দীর্ঘ নয়, আপনার প্রকল্পের প্রাসঙ্গিক বিষয়টি ভবিষ্যতে কোনও সময় সরিয়ে নেওয়া বা অপসারণের ক্ষেত্রে আপনার উত্তরের প্রাসঙ্গিক টুকরো অন্তর্ভুক্ত করা উচিত।
গ্যাভিন

ধন্যবাদ, আপনার সমাধানটি আমার ক্ষেত্রে কাজ করে যেখানে আমার ইউআইভিউয়ের স্বচ্ছ অংশটি স্পর্শ ইভেন্টগুলিতে সাড়া দেওয়ার জন্য প্রয়োজন, যখন স্বচ্ছ অংশটি না করে। উজ্জ্বল!
ব্রুস

@ ব্রুস এতে খুশী হয়েছে!
সেজেভ

4

আমার ধারণা আমি এই পার্টিতে কিছুটা দেরি করেছি, তবে আমি এই সম্ভাব্য সমাধানটি যোগ করব:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView != self) return hitView;
    return [self superview];
}

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

-Ash


1
এটি আমার পছন্দের পদ্ধতি ব্যতীত, আমার মনে হয় না আপনি ফিরে আসবেন [self superview]। এই পদ্ধতির নথির বিবরণে বলা হয়েছে যে "ভিউ হায়ারার্কিতে রিসিভারের সর্বাধিক বংশধরকে ফিরিয়ে আনা হয় (নিজেই অন্তর্ভুক্ত) যা একটি নির্দিষ্ট বিন্দু ধারণ করে" এবং "পয়েন্টটি রিসিভারের দর্শন শ্রেণিবদ্ধের বাইরে পুরোপুরি থাকে কিনা"। আমার মনে হয় আপনার ফিরে আসা উচিত nil। আপনি যখন শূন্য ফিরে আসবেন, ততক্ষণ কোনও নিয়ন্ত্রণ আছে কিনা তা পরীক্ষা করার জন্য নিয়ন্ত্রণ তদারকিতে চলে যাবে। সুতরাং মূলত এটি একই জিনিসটি করবে, তদারকি করা ফিরিয়ে দেওয়া ভবিষ্যতে কিছু ভাঙ্গতে পারে except
jasongregori

অবশ্যই, এটি বুদ্ধিমান হতে চাই (আমার মূল উত্তরের তারিখটি নোট করুন - তখন থেকে আরও অনেক কোডিং হয়েছে)
অ্যাশ

4

কেবল স্বীকৃত উত্তরের উপর রিফিং করা এবং এটি আমার রেফারেন্সের জন্য এখানে রাখছি। স্বীকৃত উত্তর পুরোপুরি কাজ করে। আপনার দৃশ্যের সংক্ষিপ্তসারগুলি স্পর্শ পাওয়ার অনুমতি দিতে বা এটি আমাদের পিছনে কোনও দৃশ্যে প্রেরণ করতে আপনি এটি এর প্রসারিত করতে পারেন:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // If one of our subviews wants it, return YES
    for (UIView *subview in self.subviews) {
        CGPoint pointInSubview = [subview convertPoint:point fromView:self];
        if ([subview pointInside:pointInSubview withEvent:event]) {
            return YES;
        }
    }
    // otherwise return NO, as if userInteractionEnabled were NO
    return NO;
}

দ্রষ্টব্য: আপনাকে সাবউভিউ ট্রিতে পুনরাবৃত্তি করতে হবে না, কারণ প্রতিটি pointInside:withEvent:পদ্ধতি আপনার পক্ষে এটি পরিচালনা করবে।


3

ব্যবহারকারীর পরিচয় সম্পত্তি অক্ষম করা সহায়তা করতে পারে। উদাহরণ:

UIView * topView = [[TOPView alloc] initWithFrame:[self bounds]];
[self addSubview:topView];
[topView setUserInteractionEnabled:NO];

(দ্রষ্টব্য: উপরের কোডে 'স্ব' একটি দর্শনকে বোঝায়)

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


3

এই পদ্ধতিটি বেশ পরিষ্কার এবং স্বচ্ছ সাবউভিউগুলি স্পর্শগুলিতেও প্রতিক্রিয়া ব্যক্ত করছে না। কেবলমাত্র সাবক্লাস UIViewএবং এর প্রয়োগের জন্য নিম্নলিখিত পদ্ধতিটি যুক্ত করুন:

@implementation PassThroughUIView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    for (UIView *v in self.subviews) {
        CGPoint localPoint = [v convertPoint:point fromView:self];
        if (v.alpha > 0.01 && ![v isHidden] && v.userInteractionEnabled && [v pointInside:localPoint withEvent:event])
            return YES;
    }
    return NO;
}

@end

2

আমার সমাধান এখানে:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    CGPoint pointInView = [self.toolkitController.toolbar convertPoint:point fromView:self];

    if ([self.toolkitController.toolbar pointInside:pointInView withEvent:event]) {
       self.userInteractionEnabled = YES;
    } else {
       self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}

আশাকরি এটা সাহায্য করবে


2

উভয় মতামতের স্পর্শকে বিরত রাখতে আপনি কিছু করতে পারেন।

শীর্ষ দেখুন:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   // Do code in the top view
   [bottomView touchesBegan:touches withEvent:event]; // And pass them on to bottomView
   // You have to implement the code for touchesBegan, touchesEnded, touchesCancelled in top/bottom view.
}

তবে এটাই ধারণা।


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

আমি নিশ্চিত না আমাদের সম্ভবত এটি চেষ্টা করা উচিত।
আলেকজান্দ্রে ক্যাসাগনে

2

এখানে একটি সুইফ্ট সংস্করণ রয়েছে:

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    return !CGRectContainsPoint(buttonView.frame, point)
}

2

সুইফট 3

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    for subview in subviews {
        if subview.frame.contains(point) {
            return true
        }
    }
    return false
}

1

আমি ইউআই টুলকিটটি ব্যবহার করে কখনই একটি সম্পূর্ণ ব্যবহারকারী ইন্টারফেস তৈরি করি নি, তাই এর সাথে আমার খুব বেশি অভিজ্ঞতা নেই। যদিও আমি মনে করি এটি কাজ করা উচিত।

প্রতিটি ইউআইভিউ, এবং এটির ইউআইওয়াইন্ডোর একটি সম্পত্তি রয়েছে subviewsযা একটি এনএসআরাই যা সমস্ত সংক্ষিপ্তসারগুলি সমন্বিত।

আপনি যে ভিউতে প্রথম সংক্ষিপ্তসার যুক্ত করবেন তা সূচক 0 এবং পরবর্তী সূচক 1 এবং এর আগে পাবেন। আপনি শ্রেণিবিন্যাসে আপনার মতামতের অবস্থান নির্ধারণ করতে পারে এমন বা এমন পদ্ধতিগুলির addSubview:সাথে প্রতিস্থাপনও করতে পারেন ।insertSubview: atIndex:insertSubview:aboveSubview:

সুতরাং আপনার ইউআই উইন্ডোতে আপনি প্রথমে কোন ভিউ যুক্ত করেন তা দেখতে আপনার কোড পরীক্ষা করুন। এটি 0 হবে, অন্যটি 1 হবে
Now এখন, আপনার একটির পূর্বরূপ থেকে, অন্যটিতে পৌঁছানোর জন্য আপনি নিম্নলিখিতটি করতে হবে:

UIView * theOtherView = [[[self superview] subviews] objectAtIndex: 0];
// or using the properties syntax
UIView * theOtherView = [self.superview.subviews objectAtIndex:0];

এটি যদি আপনার মামলার পক্ষে কাজ করে তবে আমাকে জানান!


(এই চিহ্নিতকারীর নীচে আমার পূর্ববর্তী উত্তর):

যদি মতামতগুলির একে অপরের সাথে যোগাযোগের প্রয়োজন হয় তবে তাদের নিয়ন্ত্রণকারীর মাধ্যমে এটি করা উচিত (এটি জনপ্রিয় এমভিসি মডেল ব্যবহার করে )।

আপনি যখন একটি নতুন ভিউ তৈরি করেন, আপনি নিশ্চিত করতে পারেন যে এটি কোনও নিয়ামকের সাথে নিবন্ধিত হয়।

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

যদি আপনার দৃশ্যের নিয়ামকের পিছনে কোনও লিঙ্ক না থাকে (তবে এটি হতে পারে) তবে আপনি আপনার নিয়ামকের রেফারেন্স পেতে সিলেটলেট এবং / অথবা শ্রেণি পদ্ধতি ব্যবহার করতে পারেন ।


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

আমাদের ইউআইভিউগুলির শীর্ষে কি আপনার কোনও ইউআইউইন্ডো রয়েছে? যদি আপনি করেন, ইভেন্টগুলি প্রচার করা উচিত এবং আপনার কোনও "যাদু" করার দরকার নেই। অ্যাপল ডেভ সেন্টারে [উইন্ডো এবং ভিউজ] [1] সম্পর্কে পড়ুন (এবং যে কোনও উপায়ে যদি এটি আপনাকে সহায়তা না করে তবে অন্য মন্তব্য যুক্ত করুন!) [1]: বিকাশকারী
ন্যাশ

হ্যাঁ, একেবারে - শ্রেণিবিন্যাসের শীর্ষে একটি ইউআই উইন্ডো।
delany

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

আপনার সাহায্যের জন্য ন্যাশ ধন্যবাদ - তবে আমি এই ইন্টারফেসগুলি তৈরির ক্ষেত্রে মোটামুটি অভিজ্ঞ এবং আমার বর্তমানটি সঠিকভাবে সেট আপ করা হয়েছে যতটা আমি জানি is বিষয়টি অন্যদের শীর্ষে রাখা হলে বিষয়টি সম্পূর্ণ দর্শনের ডিফল্ট আচরণ বলে মনে হয়।
delany

1

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

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ;
{   // cannot handle this event. pass off to super
    [self.superview touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event]; }

এই টাচস বিগানটি একটি প্রতিক্রিয়াশীল এপিআই, সুতরাং আপনাকে এটি আপনার সরকারী বা ব্যক্তিগত ইন্টারফেসে ঘোষণা করার দরকার নেই; এটি সেই ম্যাজিক এপিগুলির মধ্যে একটি যা আপনার কেবলমাত্র জানতে হবে। এই স্ব.সুপারভিউ অনুরোধটি শেষ পর্যন্ত ভিউকন্ট্রোলারের কাছে বুবল করবে। ভিউকন্ট্রোলারে, তারপরে, টাচটি পরিচালনা করতে এই টাচগুলি প্রয়োগ করুন।

নোট করুন যে স্পর্শের অবস্থানটি (সিজিপিয়েন্ট) আপনার জন্য পরিবেষ্টিত দৃশ্যের তুলনায় স্বয়ংক্রিয়ভাবে সামঞ্জস্য হয়েছে কারণ এটি ভিউয়ের ক্রমবর্ধমান শৃঙ্খলাটিকে বাউনস করে।


1

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

 for(UIGestureRecognizer *recognizer in topView.gestureRecognizers)
 {
     recognizer.delegate=self;
     [bottomView addGestureRecognizer:recognizer];   
 }
 topView.abView.userInteractionEnabled=NO; 

এবং বাস্তবায়ন UIGestureRecognizerDelegate:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

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


1

হিটটেষ্ট ভিত্তিক সমাধানের জন্য সুইফট 4 বাস্তবায়ন

let hitView = super.hitTest(point, with: event)
if hitView == self { return nil }
return hitView

0

স্টুয়ার্টের দুর্দান্ত, এবং বেশিরভাগ বোকামি উত্তর এবং সেজেভের কার্যকর বাস্তবায়ন থেকে প্রাপ্ত, এখানে একটি সুইফট 4 প্যাকেজ রয়েছে যা আপনি যে কোনও প্রকল্পে ফেলে দিতে পারেন:

extension UIColor {
    static func colorOfPoint(point:CGPoint, in view: UIView) -> UIColor {

        var pixel: [CUnsignedChar] = [0, 0, 0, 0]

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

        let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)

        context!.translateBy(x: -point.x, y: -point.y)

        view.layer.render(in: context!)

        let red: CGFloat   = CGFloat(pixel[0]) / 255.0
        let green: CGFloat = CGFloat(pixel[1]) / 255.0
        let blue: CGFloat  = CGFloat(pixel[2]) / 255.0
        let alpha: CGFloat = CGFloat(pixel[3]) / 255.0

        let color = UIColor(red:red, green: green, blue:blue, alpha:alpha)

        return color
    }
}

এবং তারপরে হিটটেষ্ট সহ:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    guard UIColor.colorOfPoint(point: point, in: self).cgColor.alpha > 0 else { return nil }
    return super.hitTest(point, with: event)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.