[ios] हटाने के लिए स्वाइप करें और "अधिक" बटन (जैसे आईओएस 7 पर मेल ऐप में)



Answers

मैंने swippable बटन को लागू करने के लिए एक नई लाइब्रेरी बनाई है जो विभिन्न प्रकार के संक्रमण और आईओएस 8 मेल एप जैसे विस्तार योग्य बटन का समर्थन करता है।

https://github.com/MortimerGoro/MGSwipeTableCell

यह लाइब्रेरी UITableViewCell बनाने और आईओएस 5, आईओएस 6, आईओएस 7 और आईओएस 8 पर परीक्षण के सभी अलग-अलग तरीकों से संगत है।

यहां कुछ संक्रमणों का नमूना है:

सीमा संक्रमण:

क्लिप संक्रमण

3 डी संक्रमण:

Question

उपयोगकर्ता दृश्य तालिका में सेल को स्वाइप करते समय "अधिक" बटन कैसे बनाएं (जैसे आईओएस 7 में मेल ऐप)

मैं यहां और कोको टच फोरम में इस जानकारी की तलाश कर रहा हूं, लेकिन मुझे जवाब नहीं मिल रहा है और मुझे उम्मीद है कि किसी से भी ज्यादा स्मार्ट मुझे समाधान दे सकता है।

मुझे यह पसंद है कि जब उपयोगकर्ता एक से अधिक संपादन बटन प्रदर्शित करने के लिए तालिका दृश्य कक्ष को स्वाइप करता है (वह डिफ़ॉल्ट रूप से डिलीट बटन होता है)। आईओएस 7 के लिए मेल ऐप में आप हटाने के लिए स्वाइप कर सकते हैं, लेकिन एक "अधिक" बटन दिखाई देता है जो दिखाता है।




आईओएस 11 के रूप में यह सार्वजनिक रूप से UITableViewDelegate में उपलब्ध है। यहां कुछ नमूना कोड दिया गया है:

- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
                                                                         title:@"DELETE"
                                                                       handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
                                                                           NSLog(@"index path of delete: %@", indexPath);
                                                                           completionHandler(YES);
                                                                       }];

    UIContextualAction *rename = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
                                                                         title:@"RENAME"
                                                                       handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
                                                                           NSLog(@"index path of rename: %@", indexPath);
                                                                           completionHandler(YES);
                                                                       }];

    UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[rename, delete]];
    swipeActionConfig.performsFirstActionWithFullSwipe = NO;

    return swipeActionConfig;
}

भी उपलब्ध:

- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath;

डॉक्स: https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview?language=objc




मुझे आशा है कि आप तब तक इंतजार नहीं कर सकते जब तक कि सेब आपको जो भी चाहिए उसे सही न हो? तो यहाँ मेरा विकल्प है।

एक कस्टम सेल बनाएँ। इसमें दो uiviews है

1. upper
2. lower

निचले दृश्य में, आपको जो भी बटन चाहिए, उसे जोड़ें। किसी भी अन्य IBActions की तरह अपने कार्यों को सौदा करें। आप एनीमेशन समय, शैली और कुछ भी तय कर सकते हैं।

अब ऊपरी दृश्य में एक उइस्वाइपजेस्टर जोड़ें और स्वाइप जेश्चर पर अपना निचला दृश्य प्रकट करें। मैंने पहले और यह सबसे सरल विकल्प किया है जहां तक ​​मेरा संबंध है।

आशा है कि मदद करें।




यहां एक सरल समाधान है। यह UITableViewCell के अंदर कस्टम UIView को प्रदर्शित और छुपाने में सक्षम है। तर्क प्रदर्शित करना UITableViewCell, BaseTableViewCell से विस्तारित कक्षा के अंदर निहित है।

BaseTableViewCell.h

#import <UIKit/UIKit.h>

@interface BaseTableViewCell : UITableViewCell

@property(nonatomic,strong)UIView* customView;

-(void)showCustomView;

-(void)hideCustomView;

@end

BaseTableViewCell.M

#import "BaseTableViewCell.h"

@interface BaseTableViewCell()
{
    BOOL _isCustomViewVisible;
}

@end

@implementation BaseTableViewCell

- (void)awakeFromNib {
    // Initialization code
}

-(void)prepareForReuse
{
    self.customView = nil;
    _isCustomViewVisible = NO;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

-(void)showCustomView
{
    if(nil != self.customView)
    {
        if(!_isCustomViewVisible)
        {
            _isCustomViewVisible = YES;

            if(!self.customView.superview)
            {
                CGRect frame = self.customView.frame;
                frame.origin.x = self.contentView.frame.size.width;
                self.customView.frame = frame;
                [self.customView willMoveToSuperview:self.contentView];
                [self.contentView addSubview:self.customView];
                [self.customView didMoveToSuperview];
            }

            __weak BaseTableViewCell* blockSelf = self;
            [UIView animateWithDuration:.5 animations:^(){

                for(UIView* view in blockSelf.contentView.subviews)
                {
                    CGRect frame = view.frame;
                    frame.origin.x = frame.origin.x - blockSelf.customView.frame.size.width;
                    view.frame = frame;
                }
            }];
        }
    }
}

-(void)hideCustomView
{
    if(nil != self.customView)
    {
        if(_isCustomViewVisible)
        {
            __weak BaseTableViewCell* blockSelf = self;
            _isCustomViewVisible = NO;
            [UIView animateWithDuration:.5 animations:^(){
                for(UIView* view in blockSelf.contentView.subviews)
                {
                    CGRect frame = view.frame;
                    frame.origin.x = frame.origin.x + blockSelf.customView.frame.size.width;
                    view.frame = frame;
                }
            }];
        }
    }
}

@end

इस कार्यक्षमता को प्राप्त करने के लिए, बेसटेबल व्यूसेल से अपने टेबल व्यू सेल को सरल बनाएं।

इसके बाद, UIViewController के अंदर, जो UITableViewDelegate को कार्यान्वित करता है, बाएं और दाएं स्वाइप को संभालने के लिए दो इशारा पहचानकर्ता बनाते हैं।

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self.tableView registerNib:[UINib nibWithNibName:CUSTOM_CELL_NIB_NAME bundle:nil] forCellReuseIdentifier:CUSTOM_CELL_ID];

    UISwipeGestureRecognizer* leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipe:)];
    leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:leftSwipeRecognizer];

    UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipe:)];
    rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:rightSwipeRecognizer];
}

दो स्वाइप हैंडलर जोड़ने से पहले

- (void)handleLeftSwipe:(UISwipeGestureRecognizer*)recognizer
{
    CGPoint point = [recognizer locationInView:self.tableView];
    NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];

    UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];

    if([cell respondsToSelector:@selector(showCustomView)])
    {
        [cell performSelector:@selector(showCustomView)];
    }
}

- (void)handleRightSwipe:(UISwipeGestureRecognizer*)recognizer
{
    CGPoint point = [recognizer locationInView:self.tableView];
    NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];

    UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];

    if([cell respondsToSelector:@selector(hideCustomView)])
    {
        [cell performSelector:@selector(hideCustomView)];
    }
}

अब, UITableViewDelegate के CellForRowAtIndexPath के अंदर, आप कस्टम UIView बना सकते हैं और इसे डिस्क्लेड सेल से जोड़ सकते हैं।

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCellTableViewCell* cell = (CustomCellTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"CustomCellTableViewCell" forIndexPath:indexPath];

    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"CellCustomView"
                                                      owner:nil
                                                    options:nil];

    CellCustomView* customView = (CellCustomView*)[ nibViews objectAtIndex: 0];

    cell.customView = customView;

    return cell;
}

बेशक, कस्टम UIView लोड करने का यह तरीका सिर्फ इस उदाहरण के लिए है। जैसा आप चाहते हैं उसे प्रबंधित करें।




किसी पुस्तकालय का उपयोग किए बिना स्विफ्ट 3 संस्करण कोड:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        tableView.tableFooterView = UIView(frame: CGRect.zero) //Hiding blank cells.
        tableView.separatorInset = UIEdgeInsets.zero
        tableView.dataSource = self
        tableView.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 4
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)

        return cell
    }

    //Enable cell editing methods.
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

        let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
            //self.isEditing = false
            print("more button tapped")
        }
        more.backgroundColor = UIColor.lightGray

        let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
            //self.isEditing = false
            print("favorite button tapped")
        }
        favorite.backgroundColor = UIColor.orange

        let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
            //self.isEditing = false
            print("share button tapped")
        }
        share.backgroundColor = UIColor.blue

        return [share, favorite, more]
    }

}



यह एक निजी एपीआई (बल्कि हास्यास्पद) है।

निम्नलिखित दो विधियां निजी हैं और UITableView के प्रतिनिधि को भेजी गई हैं:

-(NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath;

वे सुंदर आत्म व्याख्यात्मक हैं।




SwipeCellKit नामक एक अद्भुत लाइब्रेरी है, इसे और अधिक स्वीकृति प्राप्त करनी चाहिए। मेरी राय में यह MGSwipeTableCell से कूलर है। उत्तरार्द्ध मेल ऐप की कोशिकाओं के व्यवहार को पूरी तरह से दोहराता नहीं है जबकि SwipeCellKit करता है। एक नज़र देख लो




तेजी से प्रोग्रामिंग के लिए

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
  if editingStyle == UITableViewCellEditingStyle.Delete {
    deleteModelAt(indexPath.row)
    self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
  }
  else if editingStyle == UITableViewCellEditingStyle.Insert {
    println("insert editing action")
  }
}

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
  var archiveAction = UITableViewRowAction(style: .Default, title: "Archive",handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
        // maybe show an action sheet with more options
        self.tableView.setEditing(false, animated: false)
      }
  )
  archiveAction.backgroundColor = UIColor.lightGrayColor()

  var deleteAction = UITableViewRowAction(style: .Normal, title: "Delete",
      handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
        self.deleteModelAt(indexPath.row)
        self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic);
      }
  );
  deleteAction.backgroundColor = UIColor.redColor()

  return [deleteAction, archiveAction]
}

func deleteModelAt(index: Int) {
  //... delete logic for model
}



मैं अपने ऐप में एक ही कार्यक्षमता जोड़ना चाहता था, और कई अलग-अलग ट्यूटोरियल ( raywenderlich सर्वश्रेष्ठ DIY समाधान होने के बाद) के माध्यम से जाने के बाद, मुझे पता चला कि ऐप्पल का अपना raywenderlich क्लास है, जो बहुत आसान है।

आपको टेबलव्यू की बॉयलरपॉइंट विधि को इस में बदलना होगा:

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {
    // 1   
    var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    // 2
    let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet)

    let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil)
    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)

    shareMenu.addAction(twitterAction)
    shareMenu.addAction(cancelAction)


    self.presentViewController(shareMenu, animated: true, completion: nil)
    })
    // 3
    var rateAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Rate" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    // 4
    let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .ActionSheet)

    let appRateAction = UIAlertAction(title: "Rate", style: UIAlertActionStyle.Default, handler: nil)
    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)

    rateMenu.addAction(appRateAction)
    rateMenu.addAction(cancelAction)


    self.presentViewController(rateMenu, animated: true, completion: nil)
    })
    // 5
    return [shareAction,rateAction]
  }

आप इस साइट पर इसके बारे में अधिक जानकारी प्राप्त कर सकते हैं। पृष्ठभूमि रंग बदलने के लिए ऐप्पल का अपना दस्तावेज़ वास्तव में उपयोगी है:

कार्रवाई बटन का पृष्ठभूमि रंग।

घोषणा ऑब्जेक्टिव-सी @ प्रॉपर्टी (गैर-रचनात्मक, प्रतिलिपि) यूआईसीओलर * पृष्ठभूमि रंग चर्चा इस बटन का उपयोग अपने बटन के लिए पृष्ठभूमि रंग निर्दिष्ट करने के लिए करें। यदि आप इस प्रॉपर्टी के लिए कोई मान निर्दिष्ट नहीं करते हैं, तो UIKit स्टाइल प्रॉपर्टी में मान के आधार पर एक डिफ़ॉल्ट रंग असाइन करता है।

उपलब्धता आईओएस 8.0 और बाद में उपलब्ध है।

यदि आप बटन के फ़ॉन्ट को बदलना चाहते हैं, तो यह थोड़ा और मुश्किल है। मैंने एसओ पर एक और पोस्ट देखी है। कोड और साथ ही लिंक प्रदान करने के लिए, यहां वह कोड है जिसका उपयोग उन्होंने किया था। आपको बटन की उपस्थिति को बदलना होगा। आपको टेबलव्यूसेल के लिए एक विशिष्ट संदर्भ बनाना होगा, अन्यथा आप अपने ऐप में बटन की उपस्थिति बदल देंगे (मुझे वह नहीं चाहिए था, लेकिन हो सकता है, मुझे नहीं पता :))

उद्देश्य सी:

+ (void)setupDeleteRowActionStyleForUserCell {

    UIFont *font = [UIFont fontWithName:@"AvenirNext-Regular" size:19];

    NSDictionary *attributes = @{NSFontAttributeName: font,
                      NSForegroundColorAttributeName: [UIColor whiteColor]};

    NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString: @"DELETE"
                                                                          attributes: attributes];

    /*
     * We include UIView in the containment hierarchy because there is another button in UserCell that is a direct descendant of UserCell that we don't want this to affect.
     */
    [[UIButton appearanceWhenContainedIn:[UIView class], [UserCell class], nil] setAttributedTitle: attributedTitle
                                                                                          forState: UIControlStateNormal];
}

स्विफ्ट:

    //create your attributes however you want to
    let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(UIFont.systemFontSize())] as Dictionary!            

   //Add more view controller types in the []
    UIButton.appearanceWhenContainedInInstancesOfClasses([ViewController.self])

यह सबसे आसान, और सबसे स्ट्रीम-लाइन संस्करण IMHO है। आशा करता हूँ की ये काम करेगा।

अपडेट करें: यहां स्विफ्ट 3.0 संस्करण है:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    var shareAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Share", handler: {(action, cellIndexpath) -> Void in
        let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .actionSheet)

        let twitterAction = UIAlertAction(title: "Twitter", style: .default, handler: nil)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        shareMenu.addAction(twitterAction)
        shareMenu.addAction(cancelAction)


        self.present(shareMenu,animated: true, completion: nil)
    })

    var rateAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Rate" , handler: {(action, cellIndexpath) -> Void in
        // 4
        let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .actionSheet)

        let appRateAction = UIAlertAction(title: "Rate", style: .default, handler: nil)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        rateMenu.addAction(appRateAction)
        rateMenu.addAction(cancelAction)


        self.present(rateMenu, animated: true, completion: nil)
    })
    // 5
    return [shareAction,rateAction]
}





Related