单击UITableViewCell时发送到实例的无法识别的选择器

时间:2013-01-25 21:58:08

标签: ios uitableview

环顾四周,我可以看到这种类型的错误因人而异。

基本上我在ViewController中有一个UITableViewController,其中tableView是从我们的在线数据库中提取的朋友列表。我的目标是从左到右实现滑动效果手势,我找到了许多示例代码并最终使用LRSlidingTableViewCell,起初我们尝试将文件调入并适当地调用它们,我认为你应该使用作弊码叫它。它抛出的异常与我现在获得的异常相同。接受我尝试了一种新方法,因为需要在2个不同的视图(seques)上调用这个滑动效果,并决定将它们包含在我可以全局调用的MyClass中,我知道我们用于调用全局变量的编码是可靠的,我们让它工作,它在我们拥有的每个页面视图上输出当前用户登录。所以现在我已经描述了我的情况。我试图实现的目标......

继承我的错误代码,

2013-01-25 13:29:40.397 myappbeta[5496:907] -[UITableViewCell openDrawer]: unrecognized selector sent to instance 0x1ddaacb0
2013-01-25 13:29:40.399 myappbeta[5496:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell openDrawer]: unrecognized selector sent to instance 0x1ddaacb0'
*** First throw call stack:
(0x39deb2a3 0x33cda97f 0x39deee07 0x39ded531 0x39d44f68 0x123b5 0x32fdf26d 0x33061ea1 0x34be6a6f 0x39dc05df 0x39dc0291 0x39dbef01 0x39d31ebd 0x39d31d49 0x380ff2eb 0x32f712f9 0xd129 0x3759db20)
libc++abi.dylib: terminate called throwing an exception

Heres MyClass.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface JBSlidingTableViewCell : UITableViewCell {
    UIView* _bottomDrawer;
    UIView* _topDrawer;
    UILabel* _titleLabel;
}
// Callback: Called when the bottom drawer is about to be shown. Add subviews here.
- (void)bottomDrawerWillAppear;

// Callback: Called when the bottom drawer has disappeared and is about to be released.
// Release subviews here.
- (void)bottomDrawerDidDisappear;

// Creates the bottom drawer, then opens the top drawer to reveal it.
- (void)openDrawer;

// Closes the top drawer over the bottom drawer, then releases the bottom drawer.
- (void)closeDrawer;

@property (nonatomic, retain) UILabel* titleLabel;
@property (nonatomic, retain) UIView* bottomDrawer;
@property (nonatomic, retain) UIView* topDrawer;

@end



@interface MyClass : NSObject {
}
+ (NSString*)str;
+ (void)setStr:(NSString*)newStr;
+ (void)uploadImg:(UIImage*)img;
@end

现在是MyClass.m

#import "MyClass.h"
#import "QuartzCore/QuartzCore.h"

static NSString* str;

@implementation JBSlidingTableViewCell


@synthesize bottomDrawer = _bottomDrawer;
@synthesize topDrawer = _topDrawer;
@synthesize titleLabel = _titleLabel;


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)identifier {
    self = [super initWithStyle:style reuseIdentifier:identifier];

    if (nil != self) {
        self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 13, 304, 20)];
        self.titleLabel.font = [UIFont boldSystemFontOfSize:17];
        self.titleLabel.textColor = [UIColor blackColor];
        self.titleLabel.backgroundColor = [UIColor clearColor];
        [self.topDrawer addSubview:self.titleLabel];
        _bottomDrawer = nil;

        // Top drawer
        self.topDrawer = [[UIView alloc] init];
        self.topDrawer.backgroundColor = [UIColor whiteColor];
        [self.contentView addSubview:self.topDrawer];
    }

    return self;
}

- (void)dealloc {
    _bottomDrawer = nil;
    _topDrawer = nil;
    _titleLabel = nil;
}


- (void)closeDrawer {
    if (self.topDrawer.hidden) {
        CATransition* animation = [CATransition animation];
        animation.delegate = self;
        animation.type = kCATransitionPush;
        animation.subtype = kCATransitionFromLeft;
        animation.duration = 0.2f;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [self.contentView.layer addAnimation:animation forKey:nil];
        self.contentView.hidden = NO;
        self.topDrawer.hidden = NO;
    }
}

- (void)openDrawer {
    self.bottomDrawer = [[UIView alloc] initWithFrame:self.bounds];
    [self bottomDrawerWillAppear];
    [self insertSubview:self.bottomDrawer belowSubview:self.contentView];

    CATransition* animation = [CATransition animation];
    animation.type = kCATransitionPush;
    animation.subtype = kCATransitionFromRight;
    animation.duration = 0.2f;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.contentView.layer addAnimation:animation forKey:nil];
    self.topDrawer.hidden = YES;
    self.contentView.hidden = YES;
}


- (void)bottomDrawerDidDisappear {
    // Can be overridden by subclasses.
}

- (void)bottomDrawerWillAppear {
    self.bottomDrawer.backgroundColor = [UIColor lightGrayColor];
    UILabel* bottomDrawerLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 13, 304, 20)];
    bottomDrawerLabel.font = [UIFont boldSystemFontOfSize:17];
    bottomDrawerLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0];
    bottomDrawerLabel.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.75];
    bottomDrawerLabel.shadowOffset = CGSizeMake(0, 1);
    bottomDrawerLabel.backgroundColor = [UIColor clearColor];
    bottomDrawerLabel.text = [NSString stringWithFormat:@"Bottom drawer!%d",rand()];
    [self.bottomDrawer addSubview:bottomDrawerLabel];}


- (void)layoutSubviews {
    [super layoutSubviews];
    self.topDrawer.frame = self.contentView.bounds;
}
- (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag {
    [self bottomDrawerDidDisappear];
    [self.bottomDrawer removeFromSuperview];
    self.bottomDrawer = nil;
}

@end


@implementation MyClass


+ (NSString*)str {
    return str;
}

+ (void)setStr:(NSString*)newStr {
    if (str != newStr) {
        str = [newStr copy];
    }
}
+ (void)uploadImg:(UIImage*)img {
    NSData *imageData = UIImageJPEGRepresentation(img, 0.9);

    NSMutableDictionary *userDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[MyClass str],@"email", nil];
    NSString *returnString;

    NSString *urlString = @"MYURL";
    NSURL *url = [NSURL URLWithString:urlString];
    NSString *filename = [MyClass str];
    NSMutableURLRequest *request= [[NSMutableURLRequest alloc] initWithURL:url] ;

    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

    NSMutableData *postbody = [NSMutableData data];
    //NSMutableDictionary * params = [[NSMutableDictionary alloc] initWithObjects:[[NSArray alloc] initWithObjects:@"great problem", @"infront of my house",nil] forKeys:[[NSArray alloc] initWithObjects:@"problem",@"location",nil]];
    NSMutableString *tempVal = [[NSMutableString alloc] init];
    for(NSString * key in userDict)
    {
        [tempVal appendFormat:@"\r\n--%@\r\n", boundary];
        [tempVal appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@",key,[userDict objectForKey:key]];
    }

    NSString *postData = [tempVal description];
    //here Webservices is my class name
    [postbody appendData:[postData dataUsingEncoding:NSUTF8StringEncoding]];
    if(imageData != nil)
    {
        [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filetype=\"image/jpeg\"; filename=\"%@.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
        [postbody appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [postbody appendData:[NSData dataWithData:imageData]];
    }

    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"requesting upload");

   // NSString *str2 = [[NSString alloc] initWithData:postbody encoding:NSUTF8StringEncoding];
   // NSLog(str2);
    [request setHTTPBody:postbody];
    NSLog(@"uploading");

    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

    //NSLog(returnString);
    NSLog(returnString);
}

@end

现在,这里是调用storyboard中视图的文件和代码。

friendsListTableViewController.h

#import <UIKit/UIKit.h>
#import "TBXML.h"
#import <MessageUI/MessageUI.h>

@interface friendsListTableViewController: UIViewController <UIScrollViewDelegate, UITableViewDataSource, UITableViewDelegate, MFMailComposeViewControllerDelegate, NSObject, UIScrollViewDelegate>{
    NSMutableArray *friendList;
    TBXML * tbxml;
    NSMutableArray *friends;
    IBOutlet UILabel *friendsFullNames;
    IBOutlet UIImage *imageFile;
    IBOutlet UITableView *tableView;
@private
    NSIndexPath* _openedCellIndexPath;
    NSArray* _regularCellStrings;
    UITableView* _tableView;
}

    - (IBAction)inviteFriends:(id)sender;
@property (nonatomic, strong) NSMutableArray *friends;
@property (nonatomic, strong) NSMutableArray *friendList;
@property (nonatomic, retain) IBOutlet UITableView* tableView;



@end

和friendsListTableViewController.m

#import "friendsListTableViewController.h"
#import "loginViewController.h"
#import "MyClass.h"

@interface friendsListTableViewController ()
@property (nonatomic, readonly) JBSlidingTableViewCell* openedCell;
@property (nonatomic, retain) NSIndexPath* openedCellIndexPath;
@property (nonatomic, copy) NSArray* regularCellStrings;

- (void)closeOpenedCell;
@end

@implementation friendsListTableViewController
@synthesize openedCellIndexPath = _openedCellIndexPath;
@synthesize regularCellStrings = _regularCellStrings;
@synthesize tableView = _tableView;
@synthesize friends, friendList;

- (id)initWithCoder:(NSCoder*)aDecoder {
    self = [super initWithCoder:aDecoder];

    if (nil != self) {
        _openedCellIndexPath = nil;

        self.regularCellStrings = [NSArray arrayWithObjects:@"First default cell", @"Second default cell", nil];
    }

    return self;
}

- (void)dealloc {

    _openedCellIndexPath = nil;
    tableView = nil;
}


- (JBSlidingTableViewCell*)openedCell {
    JBSlidingTableViewCell* cell;

    if (nil == self.openedCellIndexPath) {
        cell = nil;
    } else {
        cell = (JBSlidingTableViewCell*)[self.tableView cellForRowAtIndexPath:self.openedCellIndexPath];
    }

    return cell;
}

#pragma mark -
#pragma mark Private Methods

- (void)closeOpenedCell {
    [self.openedCell closeDrawer];
    self.openedCellIndexPath = nil;
}

#pragma mark -
#pragma mark UIScrollViewDelegate Methods

- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView {
    [self closeOpenedCell];
}

#pragma mark -
#pragma mark UITableViewDataSource Methods

- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
    return 1;
}


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

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

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView setDelegate:self];
    [self.tableView setDataSource:self];
    friendList = [[NSMutableArray alloc] initWithCapacity:0];
    //USED TO CONNECT TO SERVERS XML

    //UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Your Userid Below :D" message:[MyClass str] delegate:self cancelButtonTitle:@"Try Agains" otherButtonTitles:nil, nil];
    //[alert show];
    NSString *someOtherString = [NSString stringWithFormat: @"MYURL?userid=%@", [MyClass str]];
    //UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Your Userid Below :D" message:someOtherString delegate:self cancelButtonTitle:@"Try Agains" otherButtonTitles:nil, nil];
    //[alert2 show];
        NSData *xmlData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:someOtherString]];
    tbxml = [[TBXML alloc]initWithXMLData:xmlData];

    //USED FOR LOCAL XML     //PLEASE USE ONLY WHEN IN DEVELOPMENT/TESTING
    //NSString *xmlData = [[NSBundle mainBundle] pathForResource:@"friendlist" ofType:@"xml"];
    //NSData *data = [[NSData alloc] initWithContentsOfFile:xmlData];
    //tbxml = [[TBXML alloc]initWithXMLData:data];

    //strings
    // Obtain root element
    TBXMLElement * root = tbxml.rootXMLElement;
    if (root)
    {
        TBXMLElement * allFriends = [TBXML childElementNamed:@"friend" parentElement:root];
        while (allFriends !=nil)
        {
            TBXMLElement * fname = [TBXML childElementNamed:@"fname" parentElement:allFriends];
            NSString *firstName = [TBXML textForElement:fname];
            TBXMLElement * lname = [TBXML childElementNamed:@"lname" parentElement:allFriends];
            NSString *lastName = [TBXML textForElement:lname];
            NSString *fullname = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
            [friendList addObject:fullname];
            allFriends = [TBXML nextSiblingNamed:@"friend" searchFromElement:allFriends];
        }

        //TBXMLElement *fname = [TBXML childElementNamed:@"fname" parentElement:elem_PLANT];
    }

}

#pragma mark - UITableViewDelegate + UITableViewDatasource

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
    return [friendList count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    // Configure the cell...
    if (nil == cell) {
        cell = [[[JBSlidingTableViewCell alloc] init]initWithStyle:UITableViewCellStyleDefault
                                                                     reuseIdentifier:CellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    friendsFullNames = (UILabel *)[cell viewWithTag:12];
    friendsFullNames.text = [friendList objectAtIndex:indexPath.row];
    imageFile = (UIImage *)[cell viewWithTag:13];
    //imageFile = [NSString stringWithFormat:@"%d", NUMBER_OF_ROWS - indexPath.row];
    //cell.textLabel.text = [friendList objectAtIndex:indexPath.row];
    return cell;
}


- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
    [self closeOpenedCell];
    [(JBSlidingTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath] openDrawer];
    self.openedCellIndexPath = indexPath;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate


- (IBAction)inviteFriends:(id)sender {

    if ([MFMailComposeViewController canSendMail]){
        // Email Subject
        NSString *emailTitle = @"Woot";
        // Email Content
        NSString *messageBody = @"Some HTML Content";
        // To address
        NSArray *toRecipents = [NSArray arrayWithObject:@"myemail@dress.com"];

        MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
        mc.mailComposeDelegate = self;
        [mc setSubject:emailTitle];
        [mc setMessageBody:messageBody isHTML:YES];
        [mc setToRecipients:toRecipents];

        // Present mail view controller on screen
        [self presentViewController:mc animated:YES completion:NULL];
    }
    else{
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Account Found" message:@"You need to add an email account to your device" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
        // optional - add more buttons:
        [alert addButtonWithTitle:@"Add Account"];
        [alert show];
    }

}


- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Mail cancelled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Mail saved");
            break;
        case MFMailComposeResultSent:
            NSLog(@"Mail sent");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Mail sent failure: %@", [error localizedDescription]);
            break;
        default:
            break;
    }

    // Close the Mail Interface
    [self dismissViewControllerAnimated:YES completion:NULL];
}

@end

在故事板中,它的标识符“Cell”是正确的,包含单元格的tableView正确地从数据库中正确地提取信息。

我们在单击单元格时收到此错误,尝试测试滑动功能。

我知道它有很多源代码可供使用。但我感谢任何时间和精力帮助我。

由于

1 个答案:

答案 0 :(得分:1)

原型的类是否设置为JBSlidingTableViewCell?似乎没有。(见我说垃圾在这里)

一般来说:

如果您在故事板中使用动态原型单元格(但是您以编程方式分配单元子视图,那么为什么您需要原型?):

你应该只用... = [[[JBSlidingTableViewCell alloc] init];创建它然后你可以放入initWithStyle:reuseIdentifier: awakeFromNib放置的自定义项(或者你可以在故事板中自定义单元格),如果你需要的话重用整个类的id,然后重写reuseIdentifier getter,并在那里返回id。