ios - UICollectionViewCell पर लंबे समय तक इशारा करें




objective-c (5)

उद्देश्य सी

आपकी myCollectionViewController.h फ़ाइल में UIGestureRecognizerDelegate प्रोटोकॉल जोड़ें

@interface myCollectionViewController : UICollectionViewController<UIGestureRecognizerDelegate>

आपके myCollectionViewController.m फ़ाइल में:

- (void)viewDidLoad
{
    // attach long press gesture to collectionView
    UILongPressGestureRecognizer *lpgr 
       = [[UILongPressGestureRecognizer alloc]
                     initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.delegate = self;
    lpgr.delaysTouchesBegan = YES;
    [self.collectionView addGestureRecognizer:lpgr];
}

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
        return;
    }
    CGPoint p = [gestureRecognizer locationInView:self.collectionView];

    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:p];
    if (indexPath == nil){
        NSLog(@"couldn't find index path");            
    } else {
        // get the cell at indexPath (the one you long pressed)
        UICollectionViewCell* cell =
        [self.collectionView cellForItemAtIndexPath:indexPath];
        // do stuff with the cell
    }
}

तीव्र

class Some {

    @objc func handleLongPress(gesture : UILongPressGestureRecognizer!) {
        if gesture.state != .Ended {
            return
        }
        let p = gesture.locationInView(self.collectionView)

        if let indexPath = self.collectionView.indexPathForItemAtPoint(p) {
            // get the cell at indexPath (the one you long pressed)
            let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
            // do stuff with the cell
        } else {
            print("couldn't find index path")
        }
    }
}

let some = Some()
let lpgr = UILongPressGestureRecognizer(target: some, action: #selector(Some.handleLongPress))

स्विफ्ट 4

class Some {

    @objc func handleLongPress(gesture : UILongPressGestureRecognizer!) {
        if gesture.state != .ended { 
            return 
        } 

        let p = gesture.location(in: self.collectionView) 

        if let indexPath = self.collectionView.indexPathForItem(at: p) { 
            // get the cell at indexPath (the one you long pressed) 
            let cell = self.collectionView.cellForItem(at: indexPath) 
            // do stuff with the cell 
        } else { 
            print("couldn't find index path") 
        }
    }
}

let some = Some()
let lpgr = UILongPressGestureRecognizer(target: some, action: #selector(Some.handleLongPress))

मैं सोच रहा था कि एक लंबी प्रेस इशारा पहचानकर्ता को एक (उपclass) UICollectionView में कैसे जोड़ना है। मैंने प्रलेखन में पढ़ा है कि इसे डिफ़ॉल्ट रूप से जोड़ा गया है, लेकिन मैं यह नहीं समझ सकता कि कैसे।

मैं क्या करना चाहता हूं: एक सेल पर लंबे समय तक दबाएं ( मेरे पास जिथब से कैलेंडर की चीज़ है), प्राप्त करें कि कौन सा सेल टैप किया गया है और फिर इसके साथ सामान करें। मुझे पता होना चाहिए कि कौन सा सेल लम्बा हुआ है। इस व्यापक प्रश्न के लिए खेद है, लेकिन मुझे Google या SO पर कुछ भी बेहतर नहीं मिला


UICollectionView के प्रतिनिधि का उपयोग लंबे प्रेस ईवेंट प्राप्त करें

आपको नीचे 3 विधि लागू करना होगा।

//UICollectionView menu delegate
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath{

   //Do something

   return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{
    //do nothing
    return NO;
}

- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{
    //do nothing
}

बाहरी इशारा पहचानकर्ता होने के लिए और UICollectionView पर आंतरिक इशारा पहचानकर्ताओं के साथ संघर्ष न करें आपको यह करने की आवश्यकता है:

अपना इशारा पहचानकर्ता जोड़ें, इसे स्थापित करें और इसके लिए कोई संदर्भ कैप्चर करें (यदि आप UICollectionView को उपclassed करते हैं तो सबसे अच्छा विकल्प आपके उप-वर्ग पर है)

@interface UICollectionViewSubclass : UICollectionView <UIGestureRecognizerDelegate>    

@property (strong, nonatomic, readonly) UILongPressGestureRecognizer *longPressGestureRecognizer;   

@end

डिफ़ॉल्ट प्रारंभिक विधियों को ओवरराइड करें initWithFrame:collectionViewLayout: और initWithCoder: और आपके लिए सेट अप विधि जोड़ें लंबे समय तक इशारा पहचानकर्ता दबाएं

@implementation UICollectionViewSubclass

-(instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
{
    if (self = [super initWithFrame:frame collectionViewLayout:layout]) {
        [self setupLongPressGestureRecognizer];
    }
    return self;
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        [self setupLongPressGestureRecognizer];
    }
    return self;
}

@end

अपनी सेटअप विधि लिखें ताकि यह लंबे प्रेस इशारा पहचानकर्ता को तुरंत चालू कर सके, इसके प्रतिनिधि को सेट करें, यूआईसीओलेक्शन व्यू इशारा पहचानकर्ता के साथ सेटअप निर्भरताएं (इसलिए यह मुख्य इशारा होगा और अन्य सभी इशारा तब तक इंतजार करेंगे जब तक कि इशारा पहचानने से पहले विफल हो जाए) और दृश्य में इशारा जोड़ें

-(void)setupLongPressGestureRecognizer
{
    _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(handleLongPressGesture:)];
    _longPressGestureRecognizer.delegate = self;

    for (UIGestureRecognizer *gestureRecognizer in self.collectionView.gestureRecognizers) {
        if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
            [gestureRecognizer requireGestureRecognizerToFail:_longPressGestureRecognizer];
        }
    }

    [self.collectionView addGestureRecognizer:_longPressGestureRecognizer];
}

UIGestureRecognizerDelegate विधियों को भी लागू करना न भूलें जो उस इशारे को विफल कर देते हैं और एक साथ पहचान की अनुमति देते हैं (आपको इसे लागू करने की आवश्यकता नहीं हो सकती है या नहीं, यह आपके इशारा पहचानकर्ताओं पर निर्भर करता है या आंतरिक इशारा पहचानकर्ताओं के साथ निर्भरता)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([self.longPressGestureRecognizer isEqual:gestureRecognizer]) {
        return NO;
    }

    return NO;
}

इसके लिए प्रमाण पत्र LXReorderableCollectionViewFlowLayout आंतरिक कार्यान्वयन के लिए जाता है


शायद, UILongPressGestureRecognizer का उपयोग सबसे व्यापक समाधान है। लेकिन मैं इसके साथ दो परेशान परेशानियों का सामना करता हूं:

  • कभी-कभी यह पहचानकर्ता गलत तरीके से काम करता है जब हम अपना स्पर्श बढ़ा रहे हैं;
  • पहचानकर्ता अन्य स्पर्श कार्यों को रोकता है ताकि हम अपने UICollectionView के हाइलाइट कॉलबैक का उचित तरीके से उपयोग नहीं कर सकें।

मुझे एक छोटे से ब्रूटफोर्स का सुझाव दें, लेकिन यह आवश्यक सुझाव के रूप में काम कर रहा है:

हमारे सेल पर लंबे समय तक क्लिक करने के लिए कॉलबैक विवरण घोषित करना:

typealias OnLongClickListener = (view: OurCellView) -> Void

चर के साथ UICollectionViewCell को विस्तारित करना (उदाहरण के लिए हम इसे OurCellView नाम दे सकते हैं):

/// To catch long click events.
private var longClickListener: OnLongClickListener?

/// To check if we are holding button pressed long enough.
var longClickTimer: NSTimer?

/// Time duration to trigger long click listener.
private let longClickTriggerDuration = 0.5

हमारे सेल वर्ग में दो तरीकों को जोड़ना:

/**
 Sets optional callback to notify about long click.

 - Parameter listener: A callback itself.
 */
func setOnLongClickListener(listener: OnLongClickListener) {
    self.longClickListener = listener
}

/**
 Getting here when long click timer finishs normally.
 */
@objc func longClickPerformed() {
    self.longClickListener?(view: self)
}

और यहाँ स्पर्श घटनाओं को ओवरराइड करना:

/// Intercepts touch began action.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    longClickTimer = NSTimer.scheduledTimerWithTimeInterval(self.longClickTriggerDuration, target: self, selector: #selector(longClickPerformed), userInfo: nil, repeats: false)
    super.touchesBegan(touches, withEvent: event)
}

/// Intercepts touch ended action.
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    longClickTimer?.invalidate()
    super.touchesEnded(touches, withEvent: event)
}

/// Intercepts touch moved action.
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    longClickTimer?.invalidate()
    super.touchesMoved(touches, withEvent: event)
}

/// Intercepts touch cancelled action.
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    longClickTimer?.invalidate()
    super.touchesCancelled(touches, withEvent: event)
}

फिर कॉलबैक श्रोता घोषित करने के हमारे संग्रह दृश्य के नियंत्रक में कहीं भी:

let longClickListener: OnLongClickListener = {view in
    print("Long click was performed!")
}

और अंततः सेलफोरइटम एट इंडेक्सपैथ में हमारी कोशिकाओं के लिए कॉलबैक सेटिंग:

/// Data population.
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
    let castedCell = cell as? OurCellView
    castedCell?.setOnLongClickListener(longClickListener)

    return cell
}

अब हम अपने कोशिकाओं पर लंबे क्लिक क्रियाओं को रोक सकते हैं।


UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];

[cell addGestureRecognizer:longPress];

और इस तरह की विधि जोड़ें।

- (void)longPress:(UILongPressGestureRecognizer*)gesture
{
    if ( gesture.state == UIGestureRecognizerStateEnded ) {

        UICollectionViewCell *cellLongPressed = (UICollectionViewCell *) gesture.view;
    }
}




uicollectionview