Searchbar cause app to crash in my ios library - ios

I'm working on an external dynamic cocoa library (dylib) that at some point provides a view with a tableview and a search bar.
I have this on the on create
- (void)viewDidLoad {
[super viewDidLoad];
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
UINib *nib = [UINib nibWithNibName:CONTACT_CELL bundle:frameworkBundle];
[[self tableView] registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self readContacts];
}
and for my tablerow delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_CELL];
if (cell == nil)
{
NSLog(#"Cell was empty!");
}
Contact *c = [contacts objectAtIndex:[indexPath row]];
[[cell labelName] setText: [c getName]];
[[cell labelPhone] setText: [c getPhone]];
return cell;
}
problem is that when i click on the searchbar the app chrashes because:
* Assertion failure in -[UISearchResultsTableView
_configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:7962
2016-02-19 17:07:00.404 HostApp[2233:20181] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason:
'UITableView (; layer = ; contentOffset: {0, 0}; contentSize: {414, 528}>)
failed to obtain a cell from its dataSource ()'
if I use
[tableView dequeueReusableCellWithIdentifier:CONTACT_CELL forIndexPath: indexPath];
* Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:6564
2016-02-19 17:37:08.254 HostApp[2691:28849] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: 'unable
to dequeue a cell with identifier ContactCell - must register a nib or
a class for the identifier or connect a prototype cell in a
storyboard'

You can't return nil in cellForRowAtIndexPath.
You can either use :
[tableView dequeueReusableCellWithIdentifier:CONTACT_CELL forIndexPath: indexPath];
Which always returns a cell, or manually alloc it :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_CELL];
if (cell == nil)
{
NSLog(#"Cell was empty!");
cell = [UITableViewCell alloc] initWithStyle:<#(UITableViewCellStyle)#> reuseIdentifier:<#(nullable NSString *)#>];
}
Contact *c = [contacts objectAtIndex:[indexPath row]];
[[cell labelName] setText: [c getName]];
[[cell labelPhone] setText: [c getPhone]];
return cell;
}

check
1.search bar delegate for what you return
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{}
2. check number of rows in section tableview deleage

Try like this
ItemCell is my nibName not an identifier
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *nib = [UINib nibWithNibName:#"ItemCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:#"ItemCell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of ItemCell
PointsItemCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ItemCell"];
return cell;
}

The problem was I registered the nib for the "normal" tableView, but not for the searchdisplaycontroller's tableView.
Using this viewDidLoad will fix the problem.
- (void)viewDidLoad {
[super viewDidLoad];
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
UINib *nib = [UINib nibWithNibName:CONTACT_CELL bundle:frameworkBundle];
[[self tableView] registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self.searchDisplayController.searchResultsTableView registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self readContacts];
}

Related

ios tableViewCell.xib file generate more than one cell

- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"FriendTableViewCell" bundle:nil] forCellReuseIdentifier:#"FIDCELL"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FriendTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FIDCELL"];
return cell;
}
This code block work but when i add new cell in FriendTableViewCell.xib not work actually i can not call new cell. How can i call this cell or this is possible ? If this question is not clear i can add image...
**
i try to call different cell from same .xib
**
Error:
I found solution i generate new .xib and call when page load both of them
[self.tableView registerNib:[UINib nibWithNibName:#"FriendTableViewCell" bundle:nil] forCellReuseIdentifier:#"FIDCELL"];
[self.tableView registerNib:[UINib nibWithNibName:#"Cell2" bundle:nil] forCellReuseIdentifier:#"FIDCELL2"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellID = #"";
if (indexPath.row % 2 == 0) {
cellID = #"FIDCELL";
} else {
cellID = #"FIDCELL2";
}
FriendTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
// Configure the cell...
cell.nameLabel.text = self.namesArray[indexPath.row];
cell.photoImageView.image = [UIImage imageNamed:self.photoNameArray[indexPath.row]];
return cell;
}
This code part totally work.
Okey so first of all , every cell should have its unique identifier so if the first cell have an identifier called "FIDCELL" the second one should have another one called "FIDCELL2" for example , and remove the following line from your viewDidLoad :
[self.tableView registerNib:[UINib nibWithNibName:#"FriendTableViewCell" bundle:nil] forCellReuseIdentifier:#"FIDCELL"];
and add this to cellForRowAtIndexPath
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCell * cell ;
if(condtion1)
{
cell = [tableView dequeueReusableCellWithIdentifier:firstCellIdentfier];
}
else if(condtion2)
{
cell = [tableView dequeueReusableCellWithIdentifier:secondCellIdentfier];
}
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:yourNibName owner:self options:nil];
if(condtion1)
{
//0 is the index of the first cell in the nib
cell = [nib objectAtIndex:0];
}
else if(condtion2)
{
//1 is the index of the second cell in the nib .
cell = [nib objectAtIndex:1] ;
}
}
//do other work
return cell ;
}
where condtion1 and and condtion2 is the conditions that will determine which cell will be chosen .

Search through the array in the searchbar

I took advantage of this article to create a search in my application. Slightly changed the code for yourself. But if I add to the array of multiple values (1-5), the search is working perfectly, but if you add an array of say 15 value, then an error takes off
2015-05-07 12:24:55.852 gfhfgh[5662:60b] *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit/UIKit-2935.138/UITableView.m:5439
2015-05-07 12:24:55.860 gfhfgh[5662:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier SearchResultsTableViewUITableViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
*** First throw call stack:
(0x2e2fdf83 0x38aaeccf 0x2e2fde5d 0x2ecabd5b 0x30c86dff 0xf00b9 0x30c4d8f7 0x30bf4c27 0x30be7c5d 0x30be7ba3 0x30bf41cd 0x30b3a167 0x30be71eb 0x30bc86fd 0x30bc848d 0x30bc9bf5 0x30c7dcc5 0x30d0c011 0x30c36109 0x30d0abcd 0x30d0aaaf 0x30b50037 0x30b4ffd7 0x30b4ffb1 0x30b3b717 0x30b3acfd 0x30b37805 0x30c16f15 0x30d0a91f 0x30b99127 0x30b993e7 0x30c15c17 0x30e9e579 0x30ca0fed 0x30b4c4e3 0x30ef3aed 0x30b13353 0x30b11a9b 0x30b4ad49 0x30b4a66f 0x30b1f8cd 0x30b1df77 0x2e2c920b 0x2e2c86db 0x2e2c6ecf 0x2e231ebf 0x2e231ca3 0x33137663 0x30b7e14d 0xfa1a9 0x38fbbab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
What is the problem?
My code
#import "StreetTableViewController.h"
#interface StreetTableViewController ()
//#interface StreetTableViewController () <UISearchDisplayDelegate>
// the items to be searched
#property (nonatomic, copy) NSArray *items;
// the current search results
#property (nonatomic, copy) NSArray *searchResults;
#end
#implementation StreetTableViewController
#pragma mark - NSCoding
// set some initial searchable items
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
_items
= [NSArray arrayWithObjects: #"bar", #"foo", #"quux",#"bar2", #"foo2", #"quux2",#"bar3", #"foo3", #"quux3",#"bar4", #"foo4", #"quux4",#"bar5", #"foo5", #"quux5",#"bar6", #"foo6", #"quux6",
#"bar7", #"foo7", #"quux7",#"bar8", #"foo8", #"quux8",#"bar9", #"foo9", #"quux9",#"bar10", #"foo10", #"quux10", nil];
}
return self;
}
#pragma mark - UISearchDisplayDelegate
// register a cell reuse identifier for the search results table view
-(void)searchDisplayController:(UISearchDisplayController *)controller
didLoadSearchResultsTableView:(UITableView *)tableView {
[tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"SearchResultsTableViewUITableViewCell"];
}
// perform the search
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString {
NSPredicate *predicate
= [NSPredicate predicateWithFormat:#"self beginswith [c] %#", searchString];
NSArray *searchResults
= [[self items] filteredArrayUsingPredicate:predicate];
[self setSearchResults:searchResults];
return YES;
}
#pragma mark - UITableViewDataSource
// check if displaying search results
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
if ([[self searchDisplayController] isActive]) {
return [[self searchResults] count];
} else {
return [[self items] count];
}
}
// check if displaying search results
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[self searchDisplayController] isActive]) {
UITableViewCell *cell
= [tableView dequeueReusableCellWithIdentifier:#"SearchResultsTableViewUITableViewCell"
forIndexPath:indexPath];
id item = [[self searchResults] objectAtIndex:[indexPath row]];
[[cell textLabel] setText:item];
return cell;
} else {
UITableViewCell *cell
= [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"
forIndexPath:indexPath];
id item = [[self items] objectAtIndex:[indexPath row]];
[[cell textLabel] setText:item];
return cell;
}
}
#pragma mark - UITableViewDelegate
// manually perform detail segue after selecting a search result
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[self searchDisplayController] isActive]) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"detailSegue" sender:cell];
}
}
#pragma mark - UIViewController
/* prepare for detail scene segue
called after cell selection in the master and
search results table views */
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UITableViewCell *cell = (UITableViewCell *)sender;
id item = nil;
if ([[self searchDisplayController] isActive]) {
NSIndexPath *indexPath
= [[[self searchDisplayController] searchResultsTableView] indexPathForCell:cell];
item = [[self searchResults] objectAtIndex:[indexPath row]];
} else {
NSIndexPath *indexPath
= [[self tableView] indexPathForCell:cell];
item = [[self items] objectAtIndex:[indexPath row]];
}
UIViewController *detail
= (UIViewController *)[segue destinationViewController];
[[detail navigationItem] setTitle:item];
}
#end
I may understood your problem (or may not...). Check if you wrote the cell identifier (SearchResultsTableViewUITableViewCell) in your SearchResultsTableViewUITableViewCell.nib file (or SearchResultsTableViewUITableViewCell.m file instead).
I think that you didn't reused cells at all. For 5 cells you didn't need that, because the UITableView needed to create 5 cells anyway (the dequeue method create (tableHeight / cellHeight) cells, and all other cell are reused).
Another option, if you registered your class but not your nib file:
add
[self.yourTableView registerNib:[UINib nibWithNibName:#"SearchResultsTableViewUITableViewCell" bundle:nil]
forCellReuseIdentifier:#"SearchResultsTableViewUITableViewCell"];

Use Storyboard Dynamic Prototypes TableViewCell for SearchDisplayController results

I'm trying to use a Storyboard Prototype Cell to display content for search results using UISearchBar. My regular Prototype Cell (when NOT searching) appears fine, however, I get the following error when I search: the array I use to filter the results is being properly populated...
-[UISearchResultsTableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit/UIKit-2903.23/UITableView.m:
my-App*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
Creating the Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell;
if (cell == nil) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
UILabel *name = (UILabel *)[cell viewWithTag:101];
name.text = #"test";
} else {
UILabel *name = (UILabel *)[cell viewWithTag:101];
if (_messages.count == 0)
name.text = #"No Messages";
else
name.text = #"username";
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
return [_searchResults count];
else {
return _messages.count;
}
}
This did not work because table view cells are registered to a only for main table view. This will not work for your search results controller table view as storyboard will allowed to do that.
Use:
[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
instead of
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Yes, you can register that class for your search table view,
[self.searchDisplayController.searchResultsTableView registerClass:[Cell class] forCellReuseIdentifier:CellIdentifier];
but that will not have any of the stuff you designed in your custom cell in storyboard. You would have to create all programmatically.
Instead of this, you can create a nib file by copying current cell in to it. and register like this.
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"searchCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:CellIdentifier];
Have you registered your nib file
[self.searchDisplayController.searchResultsTableView registerClass:[Cell class] forCellReuseIdentifier:CellIdentifier];

UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath eror

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"Cell";
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
CurrentCell *cell = (CurrentCell *)[self.tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil)
{
NSLog(#"cell == nil");
cell = [[CurrentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
NSLog(#"the cell is %#", cell);
Current *current = [currents objectAtIndex:indexPath.section];
[cell setCellWithCurrent:current];
return cell;
}
I have added reuse identifier in storyboard, set delegate and datasource but still got this error:
*** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit/UIKit-2372/UITableView.m:5471
2013-11-04 23:47:34.206 MyApp[7417:907] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
*** First throw call stack:
(0x394452a3 0x3333497f 0x3944515d 0x342082af 0x32773f79 0x325c50a1 0x325c5055 0x325c255d 0x325a730b 0x325be7c7 0x3257a803 0x35e4ed63 0x35e4e901 0x35e4f835 0x35e4f21b 0x35e4f029 0x325808eb 0x3941a6cd 0x394189c1 0x39418d17 0x3938bebd 0x3938bd49 0x377592eb 0x325cb2f9 0xec869 0x36bf7b20)
libc++abi.dylib: terminate called throwing an exception
(lldb)
How i show my view with table:
else if ([segue.identifier isEqualToString:#"showCurrents"]) {
MainViewController *mainViewController = (MainViewController*)segue.destinationViewController;
}
CurrentCell.m:
#import "CurrentCell.h"
#interface CurrentCell ()
#end
#implementation CurrentCell
{
UIColor *badgeColor;
NSString *badgeText;
}
#synthesize topTitleLabel;
#synthesize descriptionLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void) setCellWithCurrent:(Current*) current
{
NSString *title = [current title];
[self.topTitleLabel setText:title];
[self.descriptionLabel setText:[current description]];
}
#end
PS: I do not get this error immediately, but after a quick scrolling list for some time.
Use dequeueReusableCellWithIdentifier:forIndexPath: instead of dequeueReusableCellWithIdentifier:
And remove that business about checking to see if the cell is nil.
Since your cell is a custom subclass of UITableViewCell, make sure that the cell's Class is set to you custom subclass in IB (see Identity Inspector).
Try loading cell with loadNibNamed method of NSBundle.
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"Your nib file name for CurrentCell" owner:nil options:nil] objectAtIndex:0];
}

I got a signal SIGABRT and a log message

I tried to run my app and I got signal SIGABRT in the Main.m file and this log message. Help?
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '- [UITableViewController loadView] loaded the "5wY-6u-SFr-view-Zew-TR-1Cy" nib but didn't get a UITableView.'
*** First throw call stack:
(0x15d3052 0x1764d0a 0x157ba78 0x157b9e9 0x2536ae 0xea5cb 0xf358c 0xee3e8 0x307cc5 0xf1427 0xf158c 0xb6f5280 0xf15cc 0x4546b6 0x448e30 0x15d4ec9 0x275c2 0x2755a 0xccb76 0xcd03f 0xcc2fe 0x4ca30 0x4cc56 0x33384 0x26aa9 0x14bdfa9 0x15a71c5 0x150c022 0x150a90a 0x1509db4 0x1509ccb 0x14bc879 0x14bc93e 0x24a9b 0x1d42 0x1cb5)
terminate called throwing an exception
Here is the code for my table view:
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.menu count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[self.menu objectAtIndex:indexPath.row]objectForKey:#"Title"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *__strong)indexPath {
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"detailViewController"bundle:nil];
OrderViewController *orderViewController = [[OrderViewController alloc] initWithNibName:#"orderViewController"bundle:nil];
detailViewController.item = [self.menu objectAtIndex:indexPath.row];
orderViewController.itemString = [self.menu objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
}
I have seen same problem as mentioned by Hot Licks. My xib file got corrupted. You can define corruption of xib as for example, a control is wired to more than one actions, or wired with couple of ivars. Obviously, by mistake.
Fastest thing to check your xib file,right click on control and see whether it has more than one association.

Resources