简体   繁体   中英

Add a push segue to a button inside of a custom cell of a tableview

I have a project that displays a feed of statuses similar to other social networks. Each feed item has several button that do different things. 1 of the buttons opens a new viewcontroller that displays the comments that have been posted on a particular status. When this button is clicked and the view controller is opened i would like it to be a push segue so that their is a back button and the user can navigate back to the feed.

When this button is clicked and the new vc is launched some unique data about the particular status/cell being clicked needs to be sent to the "comments vc ". Where would the code for doing this go?

CUSTOM CELL .H

#import <UIKit/UIKit.h>

@interface FeedItemCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *DefaultImg;
@property (weak, nonatomic) IBOutlet UILabel *NameLabel;
@property (weak, nonatomic) IBOutlet UILabel *StatusLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;


@property (nonatomic, copy) NSString *msg_id;
@property (nonatomic, copy) NSString *status;
@property (nonatomic, weak) IBOutlet UIButton* commentButton;
@property (nonatomic, weak) IBOutlet UIButton* bumpButton;
@property (strong, nonatomic) id delegate;
-(IBAction)viewComments:(id)sender;
-(IBAction)bump:(id)sender;

@end


@protocol CustomCellProtocol <NSObject>
- (void)EBCellPressed:(NSString *)cellName;

CUSTOM CELL .M

#import "FeedItemCell.h"
#import "CommentsViewController.h"
#import "NSDate+TimeAgo.h"


@interface FeedItemCell() <WYPopoverControllerDelegate>
{


}
- (IBAction)open:(id)sender;
- (void)close:(id)sender;
@end


@implementation FeedItemCell
@synthesize commentButton;
- (instancetype)initWithDelegate:(id)delegate {
    self = [super init];
    if (self) {
        self.delegate = delegate;
        // Initialization code
    }
    return self;
}

-(IBAction)bump:(id)sender{

    [self.delegate EBCellPressed:@"NAME"];



}

- (IBAction)open:(id)sender
{

}








@end

publicFeed . M

#import "PublicFeedViewController.h"
#import "FeedItemCell.h"
#import "AFNetworking.h"
#import "UIImageView+WebCache.h"
#import "InboxDetailViewController.h"
#import "SWRevealViewController.h"
#import "CommentsViewController.h"
#import "NSDate+TimeAgo.h"


@interface PublicFeedViewController (){
    NSArray *NameLabel;
    NSArray *StatusLabel;
    NSMutableArray *feedArray;
}

@end

@implementation PublicFeedViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //The below code prompts the user for push notifications. If allowed, code in AppDelegate takes over and stores the token.
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    // Do any additional setup after loading the view.
    self.FeedTable.dataSource=self;
    self.FeedTable.delegate=self;

    // Set the side bar button action. When it's tapped, it'll show up the sidebar.
    _sidebarButton.target = self.revealViewController;
    _sidebarButton.action = @selector(revealToggle:);

    // Set the gesture
    [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSDictionary *parameters = @{@"foo": @"bar"};
    [UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE;
    [manager POST:@"www" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        //NSLog(@"JSON: %@", responseObject);

        self->feedArray = [responseObject objectForKey:@"feed"];

        [self.FeedTable reloadData];
        [UIApplication sharedApplication].networkActivityIndicatorVisible = FALSE;
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];


}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return feedArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


    NSString *CellIdentifier=@"Cell";

    FeedItemCell *Cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(!Cell){
        Cell = [[FeedItemCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }


    NSLog(@"FEED ARRAY: %@", self->feedArray);
    NSDictionary *tempDictionary= [self->feedArray objectAtIndex:indexPath.row];
    // Display recipe in the table cell
    NSString *thumb_img = [tempDictionary objectForKey:@"thumb_img"];
    NSString *thumb_path=@"http://buhzhyve.com/CI_REST_LOGIN/UPLOADS/thumbs/";
    NSString *thumb_url = [thumb_path stringByAppendingString:thumb_img];



    Cell.NameLabel.text=[tempDictionary objectForKey:@"first_name"];
    Cell.StatusLabel.text=[tempDictionary objectForKey:@"message"];
    Cell.msg_id=[tempDictionary objectForKey:@"msg_id"];
    //Cell.status=[tempDictionary objectForKey:@"message"];
    Cell.StatusLabel.lineBreakMode=0;
    Cell.StatusLabel.numberOfLines=0;
    NSString *commentCount = [tempDictionary objectForKey:@"comment_count"];
    NSString *commentButtonText =[NSString stringWithFormat:@"Comments ( %@ )",commentCount];
    [Cell.commentButton setTitle:commentButtonText  forState: UIControlStateNormal];
    NSString *bumpCount = [tempDictionary objectForKey:@"bump_count"];
    NSString *bumpButtonText =[NSString stringWithFormat:@"Bumps ( %@ )",bumpCount];
    [Cell.bumpButton setTitle:bumpButtonText  forState: UIControlStateNormal];
    //[Cell.StatusLabel sizeToFit];
    NSString *created_string=[tempDictionary objectForKey:@"created"];
    double created_double = created_string.doubleValue;
    NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:created_double];
    NSString *ago = [date timeAgo];
    Cell.timeLabel.text=ago;




    //Cell.DefaultImg.image = [UIImage imageNamed:@"buhz_mini_logo.png"];

    [Cell.DefaultImg setImageWithURL:[NSURL URLWithString:thumb_url]
                    placeholderImage:[UIImage imageNamed:@"buhz_mini_logo.png"]];
    return Cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Ideally you should do lazy loading so that instead of creating a new textView each time, you just reuse the same one.
    UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(82, 26, self.FeedTable.frame.size.width, 18)]; //This initial size doesn't matter
    NSDictionary *tempDictionary= [self->feedArray objectAtIndex:indexPath.row];
    NSString *status = [tempDictionary objectForKey:@"message"];
    temp.font =[UIFont fontWithName:@"System" size:12];
    temp.text = status;


    CGFloat textViewWidth = 218;
    CGRect tempFrame = CGRectMake(82,26,textViewWidth,18); //The height of this frame doesn't matter.
    CGSize tvsize = [temp sizeThatFits:CGSizeMake(tempFrame.size.width, tempFrame.size.height)]; //This calculates the necessary size so that all the text fits in the necessary width.

    //Add the height of the other UI elements inside your cell

    return tvsize.height + 70;


}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"commentSegue"]) {

    }
}

@end

publicfeed .h

#import <UIKit/UIKit.h>

@interface PublicFeedViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *FeedTable;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
- (IBAction)addItem;



@end

So assuming that you're creating this button in code, this is how you could handle this.

This first line tells the button that when it's pressed, it needs to call this specific selector/method sent as the action.

[button addTarget:self action:@selector(showNextViewController) forControlEvents:UIControlEventTouchUpInside]; 

Then you would create this method in the same class.

- (void) showNextViewController
{
    NewViewController *newViewController = [[NewViewController alloc] init];  //Edit this line of course to fit for your situation.  I'm not sure if you're loading from an XIB or from a Storyboard, or neither.
    newViewController.someVariable = someVariable;
    newViewController.someOtherVariable = someOtherVariable;

    [[[[[UIApplication sharedApplication] delegate] window] rootViewController].navigationController pushViewController:view animated:YES];
}

This will send the necessary data to the new view controller, and it will also display the new view on the screen with a back button.

Hope this works!

1. Ok so lets pretend this is your custom cell class. in your .h file of the custom cell you need to add a protocol.

#import <UIKit/UIKit.h>

@interface CustomCell : UIView
@property (strong, nonatomic) id delegate; //this is used for sending messages out of the custom cell

//init
- (id)initWithFrame:(CGRect)frame andCatName:(NSString *)name andDelegate:(id)delegate;

@end
@protocol CustomCellProtocol <NSObject>

-(void)customCellSelected:(NSString *)cellName;

@end

what we actually did is something like creating a custom event that the class can throw out and everyone who subscribes to that can run a method when customCellSelected is thrown.

2. now when you create each custom cell with the init method you need to provide a delegate which kind of points to which class should the custom cell transfer the call to customCellSelected so in the init method you set that delegate.

- (id)initWithFrame:(CGRect)frame andDelegate:(id)delegate {
    self = [super initWithFrame:frame];
    if (self) {
        self.delegate = delegate; //setting which class should be called when calling protocol methods.
        // Your initialization code
    }
    return self;
}

3. now in your .m file of the custom cell, when the user presses your button and you enter your method , let it be buttonPressed

- (IBAction) buttonPressed:(id)sender {
    [self.delegate customCellSelected:@"THE CELL'S NAME"]; // calling the protocol method.
} 

now the call to the delegate method should be transferred to the vc because when you create the custom cell you use initWithFrame:(CGRect)frame andDelegate:(id)delegate and you transfer self as the delegate , so when [self.delegate customCellSelected:@"THE CELL'S NAME"]; is called it is actually called on the vc.

4. this is how you create the custom cell in the vc:

customCell *tempView = [[customCell alloc] initWithFrame:CGRectMake(X, Y, Width, Height) andDelegate:self]; // here you set the vc as the delegate

5.and now all you have to do is add the method customCellSelected to your vc code so it can called when the customCell is calling it.

- (void)customCellSelected:(NSString *)cellName {
    self.selectedCell = cellName;
    [self performSegueWithIdentifier:@"SelectedCell" sender:self];
}

6.then add this in the vc:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"SelectedCell"]) {
        LevelSelectViewController *levelSelectViewController = (LevelSelectViewController *)segue.destinationViewController;
        levelSelectViewController.cellName = self.selectedCell;
    }
}

7.only thing you have to remember is to create a segue from your first vc to the second like this:

如何创建segue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM