আইওএস - একটি দৃশ্যের মাধ্যমে সমস্ত ছোঁয়া ফরোয়ার্ড করুন


141

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


2
আপনি আপনার সমস্যার সমাধান হয়েছে? যদি হ্যাঁ হয় তবে দয়া করে উত্তরটি গ্রহণ করুন যাতে অন্যের পক্ষে সমাধানটি সন্ধান করা সহজ হয় কারণ আমি একই সমস্যার মুখোমুখি।
খুশবু দেশাই

উত্তর:


121

ব্যবহারকারীর মিথস্ক্রিয়া অক্ষম করা আমার যা দরকার ছিল!

উদ্দেশ্য গ:

myWebView.userInteractionEnabled = NO;

সুইফট:

myWebView.isUserInteractionEnabled = false

এটি আমার পরিস্থিতিতে কাজ করেছে যেখানে আমার বোতামটির একটি সংক্ষিপ্তসার ছিল। আমি সাবউভিউতে ইন্টারঅ্যাকশন অক্ষম করেছি এবং বোতামটি কাজ করেছে।
সরল_কোড

2
সুইফট 4,myWebView.isUserInteractionEnabled = false
লুই 'LYRO' Dupont,

117

ওভারলে ভিউ থেকে নীচে দর্শনগুলিতে স্পর্শ করার জন্য, ইউআইভিউতে নিম্নলিখিত পদ্ধতিটি প্রয়োগ করুন:

উদ্দেশ্য গ:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"Passing all touches to the next view (if any), in the view stack.");
    return NO;
}

সুইফট 5:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    print("Passing all touches to the next view (if any), in the view stack.")
    return false
}

3
আমার একই সমস্যা আছে তবে আমি যা চাই তা যদি আমি ইঙ্গিত সহ জুম / ঘূর্ণন / চলন্ত ভিউটি করে থাকি তবে এটি হ্যাঁ ফিরে আসবে এবং বিশ্রামের ইভেন্টের জন্য এটি না ফিরে আসবে, আমি কীভাবে এটি অর্জন করতে পারি?
মিনাक्षी

@ মিনাক্ষী এটি সম্পূর্ণ ভিন্ন প্রশ্ন, এর জন্য একটি নতুন প্রশ্ন জিজ্ঞাসা করুন।
ফ্যাটি 21

তবে সচেতন থাকুন এই সহজ পদ্ধতির সাহায্যে আপনার বোতাম এবং তেমন কিছু নেই যা প্রশ্নের উপরে রয়েছে!
ফ্যাটি

56

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

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    for (UIView* subview in self.subviews ) {
        if ( [subview hitTest:[self convertPoint:point toView:subview] withEvent:event] != nil ) {
            return YES;
        }
    }
    return NO;
}

1
আপনাকে একটি কাস্টম ইউআইভিউ সাবক্লাস তৈরি করতে হবে (বা অন্য কোনও ইউআইভিউ সাবক্লাস যেমন ইউআইআইমেজভিউ বা যা কিছু) এর সাবক্লাস তৈরি করতে হবে এবং এই ফাংশনটি ওভাররাইড করতে হবে। সংক্ষেপে, সাবক্লাসে .h ফাইলে একটি সম্পূর্ণ ফাঁকা '@interface' থাকতে পারে এবং উপরের ফাংশনটি '@ বাস্তবায়ন' এর সম্পূর্ণ বিষয়বস্তু হতে পারে।
ফ্রেসিডু

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

40

@ ফ্রেসইডু উত্তরের উন্নত সংস্করণ। আপনি এই UIViewসাবক্লাসটি এর সংক্ষিপ্তসারের বাইরে ছোঁয়ার স্বচ্ছ দৃশ্য হিসাবে ব্যবহার করতে পারেন । উদ্দেশ্য-সি বাস্তবায়ন :

@interface PassthroughView : UIView

@end

@implementation PassthroughView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    for (UIView *view in self.subviews) {
        if (!view.hidden && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) {
            return YES;
        }
    }
    return NO;
}

@end

এবং সুইফটে:

class PassthroughView: UIView {
  override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    return subviews.contains(where: {
      !$0.isHidden
      && $0.isUserInteractionEnabled
      && $0.point(inside: self.convert(point, to: $0), with: event)
    })
  }
}

পরামর্শ:

বলুন তবে আপনার পিছনে টেবিলের দৃশ্য সহ একটি বড় "ধারক" প্যানেল রয়েছে। আপনি "ধারক" প্যানেলটি তৈরি করেন PassthroughView। এটি এখন কাজ করবে, আপনি "" ধারক "এর মাধ্যমে টেবিলটি স্ক্রোল করতে পারেন।

কিন্ত!

  1. "ধারক" প্যানেলের উপরে আপনার কয়েকটি লেবেল বা আইকন রয়েছে। ভুলে যাবেন না, অবশ্যই তাদের অবশ্যই ব্যবহারকারী ইন্টারঅ্যাকশনটি অফ অফ সক্রিয় চিহ্নিত করতে হবে!

  2. "ধারক" প্যানেলের উপরে আপনার কয়েকটি বোতাম রয়েছে। ভুলে যাবেন না, অবশ্যই এটি অবশ্যই ব্যবহারকারীর ইন্টারঅ্যাকশনটিকে সক্ষম করা আবশ্যক!

  3. নোট কিছুটা confusingly, "ধারক" নিজেই যে - দেখুন আপনি ব্যবহার PassthroughViewচালু - চিহ্নিত করা আবশ্যক ব্যবহারকারীর কোনো ভূমিকা সক্রিয় করুন ! এটা চালু !! (অন্যথায়, পাসথ্রুভিউতে কোডটি কখনও কল করা হবে না))


1
আমি সুইফ্টের জন্য প্রদত্ত সমাধানটি ব্যবহার করেছি। এটি আইওএস 11 এ কাজ করছে তবে প্রতিবার আইওএস 10-এ ক্রাশ হচ্ছে। খারাপ অ্যাক্সেস দেখাচ্ছে Showing কোন ধারণা?
সৌমেন

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

1
$0.isUserInteractionEnabled
ভুলেও

7

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

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

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

/** Subclass of UIStackView that does not accept touches, except for specific subviews given in the viewsWithActiveTouch array */
class NoTouchStackView: UIStackView {

  var viewsWithActiveTouch: [UIView]?

  override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {

    if let activeViews = viewsWithActiveTouch {
        for view in activeViews {
           if CGRectContainsPoint(view.frame, point) {
                return view

           }
        }
     }
     return nil
   }
}

6

আপনি যে স্পর্শগুলিকে ফোরওয়ার্ড করতে চান তা যদি কোনও সাবউভি / সুপারভাইউ না ঘটে তবে আপনি নিজের ইউআইভিউ সাবক্লাসে একটি কাস্টম সম্পত্তি সেট আপ করতে পারেন:

@interface SomeViewSubclass : UIView {

    id forwardableTouchee;

}
@property (retain) id forwardableTouchee;

এটি আপনার। মিতে সংশ্লেষিত করতে ভুলবেন না:

@synthesize forwardableTouchee;

এবং তারপরে আপনার কোনও ইউআরআইএসপেন্ডার পদ্ধতিতে নিম্নলিখিতটি অন্তর্ভুক্ত করুন:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.forwardableTouchee touchesBegan:touches withEvent:event];

}

আপনি যেখানেই আপনার ইউভিউ ভিউ ইনস্ট্যান্ট করেন না কেন, ইভেন্টগুলিতে ফরোয়ার্ড করতে চান এমন যে কোনও দৃশ্যে ফরওয়ার্ডযোগ্য টুচি সম্পত্তি সেট করুন:

    SomeViewSubclass *view = [[[SomeViewSubclass alloc] initWithFrame:someRect] autorelease];
    view.forwardableTouchee = someOtherView;

4

সুইফ্ট 5 এ

class ThroughView: UIView {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        guard let slideView = subviews.first else {
            return false
        }

        return slideView.hitTest(convert(point, to: slideView), with: event) != nil
    }
}

4

আমার একটি ইউআইএসট্যাকভিউ দিয়ে স্পর্শ করার দরকার ছিল। ভিতরে একটি ইউআইভিউ স্বচ্ছ ছিল, তবে ইউআইএসট্যাকভিউ সমস্ত স্পর্শ গ্রাস করেছে। এটি আমার পক্ষে কাজ করেছে:

class PassThrouStackView: UIStackView {

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let view = super.hitTest(point, with: event)
        if view == self {
            return nil
        }
        return view
    }
}

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


2

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

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

isUserInterationEnabled = মিথ্যা হিসাবে কিছু বলা হয়েছে আমার পরীক্ষার উপর ভিত্তি করে কোনও বিকল্প নয়।

 override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    for subview in subviews {
        if subview.hitTest(convert(point, to: subview), with: event) != nil {
            return true
        }
    }
    return false
}

1

স্ট্যাকভিউয়ের ভিতরে আমার বেশ কয়েকটি লেবেল ছিল এবং উপরের সমাধানগুলি নিয়ে আমার তেমন সাফল্য হয়নি, পরিবর্তে আমি নীচের কোডটি ব্যবহার করে আমার সমস্যার সমাধান করেছি:

    let item = ResponsiveLabel()

    // Configure label

    stackView.addArrangedSubview(item)

সাবক্লাসিং ইউআইএসট্যাকভিউ:

class PassThrouStackView:UIStackView{
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        for subview in self.arrangedSubviews {
            let convertedPoint = convert(point, to: subview)
            let labelPoint = subview.point(inside: convertedPoint, with: event)
            if (labelPoint){
                return subview
            }

        }
        return nil
    }

}

তাহলে আপনি এর মতো কিছু করতে পারেন:

class ResponsiveLabel:UILabel{
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // Respond to touch
    }
}

0

এরকম কিছু চেষ্টা করুন ...

for (UIView *view in subviews)
  [view touchesBegan:touches withEvent:event];

উপরের কোডটি আপনার টাচস বিগান পদ্ধতিতে উদাহরণস্বরূপ সমস্ত ছদ্মরূপে সমস্ত স্পর্শকে পাস করবে।


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

0

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

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

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

class PassThruStack: UIStackView {

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {

    for view in self.subviews {
        if !view.isHidden {
            let isStack = view is UIStackView
            let isButton = view is UIButton
            let isText = view is UITextField
            if isStack || isButton || isText {
                let pointInside = view.point(inside: self.convert(point, to: view), with: event)
                if pointInside {
                    return true
                }
            }
        }
    }
    return false
}

}


-1

@ পিক্সেলক্লাউডস্টভের পরামর্শ অনুসারে আপনি যদি একটি ভিউ থেকে অন্য ভিউতে ছুঁড়ে ফেলতে চান তবে এই প্রক্রিয়াটিতে কিছুটা অতিরিক্ত নিয়ন্ত্রণ রাখতে চান - সাবক্লাস ইউআইভিউ

// হেডার

@interface TouchView : UIView

@property (assign, nonatomic) CGRect activeRect;

@end

//বাস্তবায়ন

#import "TouchView.h"

@implementation TouchView

#pragma mark - Ovverride

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    BOOL moveTouch = YES;
    if (CGRectContainsPoint(self.activeRect, point)) {
        moveTouch = NO;
    }
    return moveTouch;
}

@end

ইন্টারফেসের পরে বিল্ডার টাচভিউতে কেবল দেখুন শ্রেণির সেট করুন এবং আপনার রেক্টরের সাথে সক্রিয় রেক্ট সেট করুন। এছাড়াও আপনি অন্যান্য যুক্তি পরিবর্তন করতে এবং প্রয়োগ করতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.