周りを見回すと、このタイプのエラーは人によって解決策が異なることがわかります。
基本的に、ViewController 内に UITableViewController があります。その tableView 内には、オンライン データベースから取得した友人のリストがあります。私の目標は、左から右へのスライド効果ジェスチャーを実現することでした。多くのサンプル コードを見つけ、LRSlidingTableViewCellを使用することになりました。、最初はファイルを持ってきて、それらを適切に呼び出すことを試みました。そして、今得ているものと同じ例外をスローしました。このスライディング効果を 2 つの異なるビュー (シーク) で呼び出す必要があるため、新しいメソッドを試し、グローバルに呼び出すことができる 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
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
ここに、ストーリーボードのビューが呼び出される場所へのファイルとコードがあります。
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 はデータベースから情報を正しく取得しています。
スライド機能をテストしようとしてセルをクリックすると、このエラーが発生します。
ソースコードがたくさんあることは知っています。しかし、私を助けてくれた時間と労力に感謝します。
ありがとう