I am new to Swift and I am beginning to learn XIB. I want to pressing the button appears XIB.
I using liberty ARSPopover
my error :
Warning: Attempt to present on
which is already
presenting (null)
How can I solve this problem?
My code for button :
- (IBAction)btnShoPopover:(UIBarButtonItem *)sender {
ARSPopover *popoverController = [ARSPopover new];
popoverController.sourceView = self.view;
popoverController.sourceRect = CGRectMake(370,0, 0, 0);
popoverController.contentSize = CGSizeMake(200,300);
popoverController.arrowDirection = UIPopoverArrowDirectionUp;
[self presentViewController:popoverController animated:YES completion:^{
[popoverController insertContentIntoPopover:^(ARSPopover *popover, CGSize popoverPresentedSize, CGFloat popoverArrowHeight) {
PopovViewController *poper = [[PopovViewController alloc] init];
[self presentViewController:poper animated:YES completion:nil];
}];
}];
}
I my xib don't download:
My code for xib controller:
#interface PopovViewController ()
#end
#implementation PopovViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
My controller:
#import "ResourseTableViewController.h"
#import "ProbaViewController.h"
#interface ResourseTableViewController ()
#end
#implementation ResourseTableViewController
#synthesize arrayOriginal;
#synthesize arForTable;
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary *dTmp=[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"]];
self.arrayOriginal=[dTmp valueForKey:#"Objects"];
self.arForTable=[[NSMutableArray alloc] init] ;
[self.arForTable addObjectsFromArray:self.arrayOriginal];
SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
[self.sidebarButton setTarget: self.revealViewController];
[self.sidebarButton setAction: #selector( revealToggle: )];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.arForTable 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 setIndentationLevel:[[[self.arForTable objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *d=[self.arForTable objectAtIndex:indexPath.row];
NSLog(#"Selected index data %#",d);
if([d valueForKey:#"Objects"]) {
NSArray *ar=[d valueForKey:#"Objects"];
BOOL isAlreadyInserted=NO;
for(NSDictionary *dInner in ar ){
NSInteger index=[self.arForTable indexOfObjectIdenticalTo:dInner];
isAlreadyInserted=(index>0 && index!=NSIntegerMax);
if(isAlreadyInserted) break;
}
if(isAlreadyInserted) {
[self miniMizeThisRows:ar];
} else {
NSUInteger count=indexPath.row+1;
NSMutableArray *arCells=[NSMutableArray array];
for(NSDictionary *dInner in ar ) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self.arForTable insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationNone];
}
}
}
- (IBAction)btnPopover:(id)sender {
ARSPopover *popoverController = [ARSPopover new];
popoverController.sourceView = self.view;
popoverController.sourceRect = CGRectMake(370,0, 0, 0);
popoverController.contentSize = CGSizeMake(200,300);
popoverController.arrowDirection = UIPopoverArrowDirectionUp;
[self presentViewController:popoverController animated:NO completion:^{
[popoverController insertContentIntoPopover:^(ARSPopover *popover, CGSize popoverPresentedSize, CGFloat popoverArrowHeight) {
ProbaViewController *poper = [[ProbaViewController alloc] init];
CGFloat width = popoverPresentedSize.width;
CGFloat height = popoverPresentedSize.height - popoverArrowHeight;
poper.view.frame = CGRectMake(0, 0, width, height);
popover.view.layer.backgroundColor = [UIColor clearColor].CGColor;
[popover.view addSubview:poper.view];
}];
}];
}
-(void)miniMizeThisRows:(NSArray*)ar{
for(NSDictionary *dInner in ar ) {
NSUInteger indexToRemove=[self.arForTable indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:#"Objects"];
if(arInner && [arInner count]>0){
[self miniMizeThisRows:arInner];
}
if([self.arForTable indexOfObjectIdenticalTo:dInner]!=NSNotFound) {
[self.arForTable removeObjectIdenticalTo:dInner];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:
[NSIndexPath indexPathForRow:indexToRemove inSection:0]
]
withRowAnimation:UITableViewRowAnimationNone];
}
}
}
#end
Skimming the docs, it looks like the library is very versatile with respect to what's presented in the popover. Your code provides a clue that you hope to present a custom view controller within it (a PopovViewController).
EDIT Let's find out first where the problem lies. If everything else is working properly, then this code should present a green box...
[self presentViewController:popoverController animated:YES completion:^{
[popoverController insertContentIntoPopover:^(ARSPopover *popover, CGSize popoverPresentedSize, CGFloat popoverArrowHeight) {
CGFloat width = popoverPresentedSize.width;
CGFloat height = popoverPresentedSize.height - popoverArrowHeight;
UIView *test = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
test.backgroundColor = [UIColor greenColor];
[popover.view addSubview:test];
}];
}];
If that works, we can proceed to discovering why your PopovViewController's view is causing trouble. (My guess is that it's presentation is triggering some other presentation animation that conflicts with the 3rd party library.
If you get a working green view with no warnings or errors, post the code for PopovViewController's viewDidLoad, viewWillAppear, ...didAppear, ...didLayout, etc.
Related
i am displaying list content in table view now i want when i click
one menu of list that menu content display in UIView on next screen
. how to push UITableView to UIView dynamically in iOS.
#import "SmsCategoryTitleTableViewController.h"
#import "CategoryMainWindowViewController.h"
#import "AppDelegate.h"
#import "FMDatabase.h"
#import "FMResultSet.h"
#import "SmsTitle.h"
#import "SMSCategory.h"
#import"smsDisplayViewController.h"
#interface SmsCategoryTitleTableViewController ()
#end
#implementation SmsCategoryTitleTableViewController
#synthesize theSearchBar,Id;
#synthesize theTableView;
#synthesize array;
#synthesize disableViewOverlay;
#synthesize Arrayobject;
- (void)viewDidLoad
{
[super viewDidLoad];
[self SearchBarCode];
[self GetTableData];
[self.tableView reloadData];
filteredContentList = [[NSMutableArray alloc] init];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
// [self performSelector:#selector(push:) withObject:nil afterDelay:0.2f];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
-(void)GetTableData
{
array = [[NSMutableArray alloc] init];
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDir = [docPaths objectAtIndex:0];
self.databasePath = [documentDir stringByAppendingPathComponent:#"SMS.sqlite"];
FMDatabase *database = [FMDatabase databaseWithPath:self.databasePath];
[database setLogsErrors:TRUE];
[database open];
NSString *anQuery = [[NSString alloc]initWithFormat:#"SELECT * FROM SMSnJokes
where CategoryId=%#",self.Id];
FMResultSet *results = [database executeQuery:anQuery];
while([results next])
{
SmsTitle *title=[[SmsTitle alloc]init];
title.Id = [results stringForColumn:#"Id"];
title.CategoryId = [results stringForColumn:#"CategoryId"];
title.Title = [results stringForColumn:#"Title"];
[array addObject:title];
// NSLog(#"SMS LIST %#",title.Title);
}
[database close];
}
-(void)SearchBarCode
{
self.disableViewOverlay = [[UIView
alloc]initWithFrame:CGRectMake(0.0f,44.0f,320.0f,0)];
self.disableViewOverlay.backgroundColor=[UIColor lightGrayColor];
self.disableViewOverlay.alpha = 0;
theSearchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 5, 374.0f, 50)];
theSearchBar.delegate =self;
[self.tableView addSubview:theSearchBar];
self.navigationItem.title=#"SMS LIST";
[[self tableView] setTableHeaderView:theSearchBar];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section {
// Return the number of rows in the section.
if (isSearching)
{
return [filteredContentList count];
}
else
{
return [array count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell=[tableView
dequeueReusableCellWithIdentifier:CellIdentifier ];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] ;
}
if (isSearching)
{
cell.textLabel.text = [filteredContentList objectAtIndex:indexPath.row];
}
else
{
SmsTitle *title = [array objectAtIndex:indexPath.row];
[cell.textLabel setText:[NSString stringWithFormat:#"%# ",[title
valueForKey:#"Title"]]];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)searchTableList
{
NSString *searchString =theSearchBar.text;
filteredContentList = [[NSMutableArray alloc]init];
[filteredContentList removeAllObjects];
for (SmsTitle *title in array)
{
NSString *tempStr = title.Title;
NSComparisonResult result = [tempStr compare:searchString options:
(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0,
[searchString length])];
if (result == NSOrderedSame)
{
[filteredContentList addObject:title.Title];
}
}
}
#pragma mark - Search Implementation
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.theSearchBar resignFirstResponder];
}
- (void) dismissKeyboard
{
[self.theSearchBar becomeFirstResponder];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
isSearching = YES;
[theSearchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSLog(#"Text change - %d",isSearching);
//Remove all objects first.
[filteredContentList removeAllObjects];
if([searchText length] != 0) {
isSearching = YES;
[self searchTableList];
}
else {
isSearching = NO;
}
[self.tableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
theSearchBar.text=nil;
[theSearchBar setShowsCancelButton:NO animated:YES];
[theSearchBar resignFirstResponder];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[theSearchBar setShowsCancelButton: YES animated: YES];
[self searchTableList];
[searchBar resignFirstResponder];
}
- (void)searchBar:(UISearchBar *)searchBar activate:(BOOL) active
{
self.theTableView.allowsSelection = !active;
self.theTableView.scrollEnabled = !active;
if (!active)
{
[disableViewOverlay removeFromSuperview];
[searchBar resignFirstResponder];
}
else
{
self.disableViewOverlay.alpha = 0;
[self.view addSubview:self.disableViewOverlay];
[UIView beginAnimations:#"FadeIn" context:nil];
[UIView setAnimationDuration:0.5];
self.disableViewOverlay.alpha = 0.6;
[UIView commitAnimations];
NSIndexPath *selected = [self.theTableView indexPathForSelectedRow];
if (selected)
{
[self.theTableView deselectRowAtIndexPath:selected
animated:NO];
}
}
[searchBar setShowsCancelButton:active animated:YES];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
[self.theSearchBar resignFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
textField.returnKeyType=UIReturnKeyDefault ;
return[textField resignFirstResponder];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
smsDisplayViewController *viewController1 = [[smsDisplayViewController alloc]
init];
[self.navigationController pushViewController:viewController1 animated:YES];
}
Ok got your point. I think you want to pass data of selected cell to
next UIViewController. Assume, you want to pass cell title label and
you have an array of objects. In yoursmsDisplayViewController.h
#import <UIKit/UIKit.h>
#interface smsDisplayViewController : UIViewController
#property (strong, nonatomic) NSString *cellName;
Now in your SmsCategoryTitleTableViewController.m you have
NSMutableArray *nameList;
Then in your table view delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
smsDisplayViewController *viewController1 = [self.storyboard instantiateViewControllerWithIdentifier:#"LoginIdentifier"];
viewController1.cellName=[nameList objectAtIndex:indexPath.row];
[self.navigationController pushViewController:viewController1 animated:YES];
}
UPDATE This is the code you posted first in your question.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
smsDisplayViewController *viewController1 = [[smsDisplayViewController
alloc] initWithNibName:#"viewController1" bundle:nil];
[self.navigationController pushViewController:viewController1 animated:YES];
}
Now the wrong thing you are doing here
isinitWithNibName:#"viewController1". If you are not using any nib
file then your code should be
smsDisplayViewController *viewController1 = [[smsDisplayViewController alloc] init];
[self.navigationController pushViewController:viewController1 animated:YES];
You can use Accessory Buttons in UITableView or learn more about segues.
You have to use prepareForSegue: to pass data to another ViewController.
You can learn it from Here which teaches you how to transfer data between ViewControllers while using Segue.
I'm developing a view controller for a chat application and I want to show a UIViewController that contains a UITableView (where messages are shown with different format [if is your message or if is a message from other person], a UITextField (to write your messages) and a UIButton (to send the message)
I'm using SRWebSocket example but they use a UITableViewController (that runs perfectly but don't allow me to modify tableview size or to add the others components to the view by storyboard)
This is the code that I have in my Controller:
ChatViewController.h
#import <UIKit/UIKit.h>
#import "SRWebSocket.h"
#import "ChatCell.h"
#import "Message.h"
#import "Person.h"
#import "Program.h"
#import "DateFactory.h"
#interface ChatViewController : UIViewController <UITableViewDataSource,UITableViewDelegate,SRWebSocketDelegate, UITextViewDelegate, UITextFieldDelegate>
#property (strong, nonatomic) NSDictionary *programSegue;
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, retain) IBOutlet UITextView *inputView;
- (IBAction)goingUp:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *inputText;
#end
ChatViewController.m
Code that fails:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
in:
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
{
NSLog(#"Received \"%#\"", message);
NSError *e;
NSDictionary *allJSON =
[NSJSONSerialization JSONObjectWithData: [message dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &e];
NSString *kindJSON = [allJSON objectForKey:#"kind"];
NSString *userJSON = [allJSON objectForKey:#"user"];
NSString *messageJSON = [allJSON objectForKey:#"message"];
NSArray *membersJSON = [allJSON objectForKey:#"members"];
DateFactory *dateFactory = [DateFactory alloc];
NSString *formatDate = #"dd/MM/YYYY HH:mm";
NSString *dateString = [dateFactory dateToString:[NSDate date] withFormat:formatDate];
switch([#[#"join", #"talk", #"quit"] indexOfObject:kindJSON]){
// join
case 0:
break;
// talk
case 1:
[_messages addObject:[[Message alloc] initWithMessage:messageJSON fromMe:NO]];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
break;
// quit
case 2:
[[self.navigationItem.titleView.subviews objectAtIndex:1] setText:
[NSString stringWithFormat:#"Sin conexión desde %#", dateString]];
break;
}
}
ERROR
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update'
Full code:
#import "ChatViewController.h"
#interface ChatViewController ()
#end
#implementation ChatViewController{
SRWebSocket *_webSocket;
NSMutableArray *_messages;
Person *person;
Program *program;
}
#synthesize programSegue;
#synthesize tableView;
#synthesize inputText;
#synthesize inputView = _inputView;
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
return [inputText resignFirstResponder];
}
#pragma mark - View lifecycle
- (void)viewDidLoad;
{
[super viewDidLoad];
[inputText setDelegate:self];
person = [programSegue objectForKey:#"PERSON"];
program = [programSegue objectForKey:#"PROGRAM"];
self.navigationItem.title = person.name;
// Creates picture to be shown in navigation bar
UIButton* picture = (UIButton *) [[UIImageView alloc] initWithImage:[UIImage imageNamed:person.imageURL]];
CGRect buttonFrame = picture.frame;
buttonFrame.size = CGSizeMake(38, 38);
picture.frame = buttonFrame;
UIBarButtonItem *pictureItem = [[UIBarButtonItem alloc] initWithCustomView:picture];
self.navigationItem.rightBarButtonItem = pictureItem;
// Set title and subtitle
CGRect frame = self.navigationController.navigationBar.frame;
UIView *twoLineTitleView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(frame), 0, CGRectGetWidth(frame), CGRectGetHeight(frame))];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(frame), 20)];
titleLabel.backgroundColor = [UIColor clearColor];
[titleLabel setTextColor:[UIColor whiteColor]];
titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[titleLabel setTextAlignment:NSTextAlignmentCenter];
[titleLabel setFont:[UIFont boldSystemFontOfSize:16]];
[titleLabel setShadowColor:[UIColor grayColor]];
titleLabel.text = person.name;
[twoLineTitleView addSubview:titleLabel];
UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 26, CGRectGetWidth(frame), 14)];
subTitleLabel.backgroundColor = [UIColor clearColor];
[subTitleLabel setTextColor:[UIColor whiteColor]];
subTitleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[subTitleLabel setTextAlignment:NSTextAlignmentCenter];
[subTitleLabel setFont:[UIFont boldSystemFontOfSize:12]];
[titleLabel setShadowColor:[UIColor grayColor]];
subTitleLabel.text = #"subtitleg";
[twoLineTitleView addSubview:subTitleLabel];
self.navigationItem.titleView = twoLineTitleView;
// Start messages
_messages = [[NSMutableArray alloc] init];
[self.tableView reloadData];
}
- (void)_reconnect;
{
_webSocket.delegate = nil;
[_webSocket close];
_webSocket = [[SRWebSocket alloc] initWithURLRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:
[NSString stringWithFormat:#"ws://81.45.19.228:8000/room/chat?username=enrimr&pid=%#", person.name]]]];
_webSocket.delegate = self;
//self.title = #"Opening Connection...";
[[self.navigationItem.titleView.subviews objectAtIndex:1] setText:#"Conectando..."];
[_webSocket open];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self _reconnect];
}
- (void)reconnect:(id)sender;
{
[self _reconnect];
}
- (void)viewDidAppear:(BOOL)animated;
{
[super viewDidAppear:animated];
[_inputView becomeFirstResponder];
[self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
_webSocket.delegate = nil;
[_webSocket close];
_webSocket = nil;
}
#pragma mark - UITableViewController
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return _messages.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
{
ChatCell *chatCell = (id)cell;
Message *message = [_messages objectAtIndex:indexPath.row];
chatCell.text.text = message.message;
chatCell.date.text = message.fromMe ? #"Me" : #"Other";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
Message *message = [_messages objectAtIndex:indexPath.row];
ChatCell *cell = (ChatCell *)[self.tableView dequeueReusableCellWithIdentifier:#"programCell" forIndexPath:indexPath];
if (!cell) {
if (message.fromMe){
cell = [[ChatCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SentCell"];
[cell.text setText:message.message];
[cell.date setText:#"00:00"];
}
else {
cell = [[ChatCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"ReceivedCell"];
[cell.text setText:message.message];
[cell.date setText:#"00:00"];
}
}
return cell;
}
#pragma mark - SRWebSocketDelegate
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
{
NSLog(#"Websocket Connected");
//self.title = #"Connected!";
[[self.navigationItem.titleView.subviews objectAtIndex:1] setText:#"Conectado"];
}
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
{
NSLog(#":( Websocket Failed With Error %#", error);
self.title = #"Connection Failed! (see logs)";
_webSocket = nil;
}
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
{
NSLog(#"Received \"%#\"", message);
NSError *e;
NSDictionary *allJSON =
[NSJSONSerialization JSONObjectWithData: [message dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &e];
NSString *kindJSON = [allJSON objectForKey:#"kind"];
NSString *userJSON = [allJSON objectForKey:#"user"];
NSString *messageJSON = [allJSON objectForKey:#"message"];
NSArray *membersJSON = [allJSON objectForKey:#"members"];
DateFactory *dateFactory = [DateFactory alloc];
NSString *formatDate = #"dd/MM/YYYY HH:mm";
NSString *dateString = [dateFactory dateToString:[NSDate date] withFormat:formatDate];
switch([#[#"join", #"talk", #"quit"] indexOfObject:kindJSON]){
// join
case 0:
break;
// talk
case 1:
[_messages addObject:[[Message alloc] initWithMessage:messageJSON fromMe:NO]];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
break;
// quit
case 2:
[[self.navigationItem.titleView.subviews objectAtIndex:1] setText:
[NSString stringWithFormat:#"Sin conexión desde %#", dateString]];
break;
}
}
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
{
NSLog(#"WebSocket closed");
//self.title = #"Connection Closed! (see logs)";
[[self.navigationItem.titleView.subviews objectAtIndex:1] setText:#"Offline"];
_webSocket = nil;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
{
if ([text rangeOfString:#"\n"].location != NSNotFound) {
NSString *message = [[textView.text stringByReplacingCharactersInRange:range withString:text] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[_webSocket send:message];
[_messages addObject:[[Message alloc] initWithMessage:message fromMe:YES]];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_messages.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];
textView.text = #"";
return NO;
}
return YES;
}
- (void) animateTextField: (UITextField*) textField up: (BOOL)up
{
const int movementDistance = 218;
const float movementDuration = 0.3f;
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
- (IBAction)goingUp:(id)sender {
[self animateTextField:inputText up:TRUE];
}
#end
When you use insertRowsAtIndexPaths you have to first update the table view data source. So before you call the insertRowsAtIndexPaths you should do something like _messages addObject:newMessage.
Just as a helper rule, whenever you update the rows of a table view without using reloadData method, you have to update the tableView`s data source to reflect the index paths that will be updated. So if you delete on row from your table view, the data associated with that row must be deleted from data source, also if you add a row to the table view, you have to add the associated data of the new row into the data source. ALWAYS UPDATE THE DATASOURCE FIRST.
And every time you update the rows of a table view you should use the update method between beginUpdates and endUpdates method calls.
The problem was that I forgot to set
[tableView setDataSource:self];
[tableView setDelegate:self];
in my viewDidLoad. These two lines will fix my problem.
I try to make a little program to learn more about searching a tableview about a searchbar. Meanwhile i'm in the third week trying to do this. I found many examples in different ways in the internet. The most with a searchdisplaycontroller but this way is only for a viewcontroller. i prefer a way that also works with an uiview and so i use the searchbar delegatemethod to filter my data dictionary. Normally i try as long i get handle such things by myself. But this is my nemesis. I really can't find a way to get this problem solved. Can anyone help me with my code?
Here it is.
#import "FilterDemoTableViewController.h"
#implementation FilterDemoTableViewController
#synthesize filteredTableData;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize tableContents;
#synthesize Keys;
- (void)viewDidLoad
{
[super viewDidLoad];
searchBar.delegate = (id)self;
//-----------------------My TableView Data ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
//--------------------------------------------------------------------------
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered) {
return [filteredTableData count];
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
int rowCount;
if(self.isFiltered)
rowCount = filteredTableData.count;
else
rowCount = [listData count];
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
NSDictionary* sectionDictionary;
if (isFiltered) {
sectionDictionary = [filteredTableData objectAtIndex:indexPath.section];
} else {
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
}
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
//I think here is something wrong but i don't know what
isFiltered = true;
filteredTableData = [[NSMutableArray alloc] init];
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in tableContents) //dictionary read
{
NSArray *array = [dictionary objectForKey:Keys]; //section of dictionary read
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
[filteredTableData addObject:sTemp];
}
}
[self.tableView reloadData];
}
- (void)viewDidUnload{
[self setSearchBar:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Now i post a complete refreshed code. I tested each component of the code step by step. It works and the search is also fine (in a UITableViewController). But in this example the hole code is in a UIView. The reason, on this way it is possible to create non full-size tableviews and instanzes of tableviews. Much better for a clear Viewcontroller. I know that an UIView has no method like this reloadData but it is necessary.
Near the code end you can see the problem line. And for this last step i have no idea how i can solve this. [self.tableView reloadData];
#import "TableView.h"
#import <QuartzCore/QuartzCore.h>
#interface TableView ()
#end
#implementation TableView
#synthesize delegate;
#synthesize dropDownHeight;
#synthesize labelText;
#synthesize enabled;
#synthesize tableContents;
#synthesize Keys;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize filteredTableData;
- (void)__show {
viewControl.alpha = 0.0f;
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:viewControl];
[UIView animateWithDuration:0.3f
animations:^{
viewControl.alpha = 1.0f;
}
completion:^(BOOL finished) {}];
}
- (void)__hide {
[UIView animateWithDuration:0.2f
animations:^{
viewControl.alpha = 0.0f;
}
completion:^(BOOL finished) {
[viewControl removeFromSuperview];
}];
}
- (void) setLabelText:(NSString *)_labelText{
[button setTitle:labelText forState:UIControlStateNormal];
}
- (void) setEnable:(BOOL)_enabled{
enabled = _enabled;
[button setEnabled:_enabled];
}
- (void) setArrayData:(NSArray *)_arrayData{
[table reloadData];
}
- (void) buttonPressed{
[self __show];
}
- (void) controlPressed{
//[viewControl removeFromSuperview];
[self __hide];
}
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(10, 0, 280, 30)];
[button setTitle:#"--Auswahl--" forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"combo_bg.png"] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[self addSubview:button];
dropDownHeight = 706;
viewControl = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
[viewControl addTarget:self action:#selector(controlPressed) forControlEvents:UIControlEventTouchUpInside];
CGFloat x = self.frame.origin.x;
CGFloat y = (viewControl.frame.size.height - dropDownHeight)/2;
table = [[UITableView alloc] initWithFrame:CGRectMake(x, y, frame.size.width, dropDownHeight) style:UITableViewStyleGrouped];
table.dataSource = self;
table.delegate = self;
searchBar = [[UISearchBar alloc] init];
[searchBar sizeToFit];
searchBar.delegate = (id)self;
table.tableHeaderView = searchBar;
CALayer *layer = table.layer;
layer.masksToBounds = YES;
layer.cornerRadius = 2.0f;
layer.borderWidth = 1.0f;
[layer setBorderColor:[UIColor darkGrayColor].CGColor];
[viewControl addSubview:table];
CGAffineTransform rotateTable = CGAffineTransformMakeRotation(M_PI_2);
table.transform = rotateTable;
table.frame = CGRectMake(-2, -1, table.frame.size.width, table.frame.size.height);
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"gradientBackground.png"]];
[tempImageView setFrame:self->table.frame];
table.backgroundView = tempImageView;
//----------------------- TableView Daten ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",#"Hamburg",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
// ---------------------------------------------------------------------
}
return self;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([self tableView:tableView titleForHeaderInSection:section] != nil) {
return 40;
}
else {
return 0;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
// Create label with section title
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(20, 6, 300, 30);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
label.shadowColor = [UIColor grayColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
label.font = [UIFont boldSystemFontOfSize:16];
label.text = sectionTitle;
// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
[view addSubview:label];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60.0;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
return [self.Keys objectAtIndex:section];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered)
{
return 1;
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rowCount;
if(self.isFiltered)
{
rowCount = [filteredTableData count];
}
else
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
rowCount = [listData count];
}
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
}
if (isFiltered)
{
NSString * stadt = [filteredTableData objectAtIndex:indexPath.row];
cell.textLabel.text = stadt;
}
else
{
NSDictionary* sectionDictionary;
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:[indexPath section]]];
NSUInteger row = [indexPath row];
NSString *rowValue = [listData objectAtIndex:row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndex = [indexPath row];
[self __hide];
[button setTitle:[[NSString alloc] initWithFormat:rowValue] forState:UIControlStateNormal];
}
- (NSInteger) selectedIndex {
return selectedIndex;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
[filteredTableData removeAllObjects];
for (NSString* key in self.tableContents)
{
NSArray *staedte = [self.tableContents objectForKey:key];
for (NSString *stadt in staedte)
{
NSRange titleResultsRange = [stadt rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
{
[filteredTableData addObject:stadt];
}
}
}
}
[self.tableView reloadData]; //Here is the error
}
-(void)didChangeTableViewValue:(TableView *)TableView selectedIndex:(NSInteger)selectedIndex {
}
#end
I have a mutable Array in a Tableview, this is populated on View did load from an SQLite database, However this database changes as it is a favourites database for products in my app.
When a user selects one of the items in the tableview (The user then goes to a detail view, with the info from the database) the user can then select to remove it from the favourites (database) when the user then presses back in the navigation bar, the item is still there, I've tried tableview reload on view did appear, and view will appear but that doesn't help,
Can anyone shed any light on this??
Many thanks,
Andrew
Here is my code:
FavTableViewController.h:
#interface FavTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *Table;
}
#property (nonatomic, strong) UITableView *Table;
#property (nonatomic, strong) NSArray *cats;
#property (nonatomic, strong) IBOutlet UISearchBar *searchBar;
#property (nonatomic, strong) UISearchDisplayController *searchDisplayController;
#property (nonatomic, strong) NSMutableArray *filteredListContent;
#property (nonatomic, strong) NSMutableArray *listContent;
#property (nonatomic, strong) NSArray *everything;
#property (nonatomic, copy) NSString *savedSearchTerm;
#property (nonatomic) NSInteger savedScopeButtonIndex;
#property (nonatomic) BOOL searchWasActive;
#property (nonatomic, strong) NSString *cellText;
-(void) refresh;
#end
FavTableViewController.m:
#import "FavTableViewController.h"
#import "DBFavAdapter.h"
#import "MenuData.h"
#import "DBAdapter.h"
#import "DetailViewController.h"
#import "ConsoleDetailController.h"
#import "EffectDetailViewController.h"
#import "DimmersDetailController.h"
#import "ConventionalController.h"
#import "ProDetailViewController.h"
#implementation FavTableViewController
#synthesize filteredListContent, savedSearchTerm, savedScopeButtonIndex, searchWasActive, searchBar, searchDisplayController, listContent, everything, cellText, cats, Table;
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
listContent = [[NSMutableArray alloc] init];
}
return self;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
NSLog(#"Did Load");
[super viewDidLoad];
everything = [[DBFavAdapter allProducts] mutableCopy];
for (NSDictionary *dict in everything) {
[listContent addObject: [dict objectForKey:#"Title"]];
}
// create a filtered list that will contain products for the search results table.
self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.listContent count]];
// restore search settings if they were saved in didReceiveMemoryWarning.
if (self.savedSearchTerm)
{
[self.searchDisplayController setActive:self.searchWasActive];
[self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
[self.searchDisplayController.searchBar setText:savedSearchTerm];
self.savedSearchTerm = nil;
}
// [self.tableView reloadData];
self.Table.scrollEnabled = YES;
self.navigationItem.title = #"Favourites";
// cats = [DBFavAdapter allCategories];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.filteredListContent = nil;
NSLog(#"Unload");
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(#"View will Appear");
[Table reloadData];
NSLog(#"Everything: %#",everything);
NSLog(#"list Content: %#",listContent);
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"View did Appear");
[super viewDidAppear:animated];
NSLog(#"list Content appeared: %#",listContent);
[Table reloadData];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
NSLog(#"Did dissapear");
// save the state of the search UI so that it can be restored if the view is re-created
self.searchWasActive = [self.searchDisplayController isActive];
self.savedSearchTerm = [self.searchDisplayController.searchBar text];
self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(tableView == self.searchDisplayController.searchResultsTableView){
return [self.filteredListContent count];
}
else {
return [self.listContent count];
}
NSLog(#"Rows %i",[self.listContent count]);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
if (tableView == searchDisplayController.searchResultsTableView)
{
cellText = [self.filteredListContent objectAtIndex:indexPath.row];
}
else
{
cellText = [self.listContent objectAtIndex:indexPath.row];
}
// NSString *cellText = [self.listContent objectAtIndex:indexPath.row];
UIFont *cellFont = [UIFont fontWithName:#"Heiti TC" size:17.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 30;
}
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = 1;
return row;
}
- (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.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Heiti TC" size:17.0];
}
// Configure the cell...
if (tableView == searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.filteredListContent objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [self.listContent objectAtIndex:indexPath.row];
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedItem;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
selectedItem = [self.filteredListContent objectAtIndex:indexPath.row];
}
else
{
selectedItem = [self.listContent objectAtIndex:indexPath.row];
}
// Is the selection a category?
// NSArray *cats = [DBAdapter allCategories];
__block BOOL cat = NO;
[cats enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([(NSString*)obj isEqualToString:selectedItem]) {
cat = YES;
*stop = YES;
}
}];
if (cat) { // the user's selection was a category
// NSLog(#"Selected item was a category");
}
else {
NSArray *mans = [DBAdapter allManufacturers];
__block BOOL man = NO;
[mans enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([(NSString*)obj isEqualToString:selectedItem]) {
man = YES;
*stop = YES;
}
}];
if (man) { // the user's selection was a manufacturer
// NSLog(#"Selected item was a manufacturer");
} else {
// the user's selection was a product
// Find selectedItem in products
__block NSDictionary *selectedRow = nil;
[self.everything enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
//everything is an array of dictionaries
if ([(NSString*)[(NSDictionary*)obj objectForKey:#"Title"] isEqualToString:selectedItem]) {
selectedRow = (NSDictionary*)obj;
*stop = YES;
}
}];
MenuData *selectionData = [MenuData menuData];
selectionData.manufacturerID = [[selectedRow objectForKey:#"Manufacturer_id"] integerValue];
selectionData.categoryID = [[selectedRow objectForKey:#"Category_id"] integerValue];
selectionData.sCategoryID = [[selectedRow objectForKey:#"SubCategory_id"] integerValue];
selectionData.ssCategoryID = [[selectedRow objectForKey:#"SuperSubCategory_id"] integerValue];
NSString *selectedTitle = [selectedRow objectForKey: #"Title"]; // You probably already have this value from your search. Here for the sake of clarity.
NSDictionary *productDetails = [DBAdapter productDetails: selectedTitle forCurrentData: selectionData];
NSArray *allKeys = [productDetails allKeys];
// NSLog(#"values: %i", [allKeys count]);
for (NSString *key in allKeys) {
id value = [productDetails objectForKey:key];
if ([value isKindOfClass:[NSString class]]) {
// NSLog(#"key: %# value: %#", key, value);
}
}
NSInteger ViewNumber = [[productDetails objectForKey:#"View"] integerValue];
switch (ViewNumber) {
case 25: {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
dvController.dictionary = productDetails;
[self.navigationController pushViewController:dvController animated:YES];
}
break;
case 18: {
EffectDetailViewController *edvController = [[EffectDetailViewController alloc] initWithNibName:#"EffectDetailView" bundle:[NSBundle mainBundle]];
edvController.dictionary = productDetails;
[self.navigationController pushViewController:edvController animated:YES];
}
break;
case 17: {
ConsoleDetailController *cdvController = [[ConsoleDetailController alloc] initWithNibName:#"ConsoleDetailController" bundle:[NSBundle mainBundle]];
cdvController.dictionary = productDetails;
[self.navigationController pushViewController:cdvController animated:YES];
}
break;
case 2: {
ConsoleDetailController *cdvController = [[ConsoleDetailController alloc] initWithNibName:#"ConsoleDetailController" bundle:[NSBundle mainBundle]];
cdvController.dictionary = productDetails;
[self.navigationController pushViewController:cdvController animated:YES];
}
break;
case 3: {
DimmersDetailController *ddvController = [[DimmersDetailController alloc] initWithNibName:#"DimmersDetailController" bundle:[NSBundle mainBundle]];
ddvController.dictionary = productDetails;
[self.navigationController pushViewController:ddvController animated:YES];
}
break;
case 12: {
ConventionalController *cController = [[ConventionalController alloc] initWithNibName:#"ConventionalController" bundle:[NSBundle mainBundle]];
cController.dictionary = productDetails;
[self.navigationController pushViewController:cController animated:YES];
}
break;
case 5: {
ProDetailViewController *pController = [[ProDetailViewController alloc] initWithNibName:#"ProDetailViewController" bundle:[NSBundle mainBundle]];
pController.dictionary = productDetails;
[self.navigationController pushViewController:pController animated:YES];
}
break;
}
}
}
}
#pragma mark -
#pragma mark Content Filtering
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
/*
Update the filtered array based on the search text and scope.
*/
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
/*
Search the main list for products whose type matches the scope (if selected) and whose name matches searchText; add items that match to the filtered array.
*/
for (NSString *product in listContent)
{
//Edit AD - NS Range works instead of NSComparisonResult
NSRange result = [product rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
if (result.location != NSNotFound)
{
[self.filteredListContent addObject:product];
}
/*
// NSComparisonResult result = [product compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredListContent addObject:product];
}
*/
}
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)refresh {
NSLog(#"Refresh");
if([NSThread isMainThread])
{
[self.Table reloadData];
[self.Table setNeedsLayout];
[self.Table setNeedsDisplay];
}
else
{
[self performSelectorOnMainThread:#selector(refresh) withObject:nil waitUntilDone:YES];
}
}
#end
You have 2 options.
Remove the item from the listContent as well. This can be done via a delegate method that will be called from the child view controller when you delete the item.
Move your viewDidLoad functionality where listContents is generated from the database to viewWillAppear. This will cause listContents to read the database again, after the item was deleted and you hit the back button, this will also get called when the view first opens.
I'm working form the big nerd ranch book, iphone programming. I'm working through Chapt 11 where you implement your own setEditing method:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if( editing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
}
else {
/*
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
*/
}
}
When I run this the whole app does a Sigabort without any info other than that. The line that seems to cause the problem is this one:
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
I'm not sure what I'm doing wrong. What else would be good to see?
This is the whole file:
//
// TeamsViewController.m
// TeamTrackerClient
//
// Created by Mark Steudel on 3/4/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "TeamsViewController.h"
#import "Team.h"
#implementation TeamsViewController
-(id) init
{
self = [super initWithStyle:UITableViewStyleGrouped];
teams = [[NSMutableArray alloc] init];
Team *team = [[Team alloc] init];
team.teamName = [NSString stringWithFormat: #"Fighting Axons"];
team.teamCode = [NSString stringWithFormat: #"FA1"];
[teams addObject:team];
Team *team2 = [[Team alloc] init];
team2.teamName = [NSString stringWithFormat: #"Pipers Peddlers"];
team2.teamCode = [NSString stringWithFormat: #"PP1"];
[teams addObject:team2];
return self;
}
- (id) initWithStyle:(UITableViewStyle)style
{
return [self init];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (UIView *) headerView
{
if( headerView)
return headerView;
UIButton *editButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[editButton setTitle: #"Edit" forState: UIControlStateNormal];
float w = [[UIScreen mainScreen] bounds].size.width;
CGRect editButtonFrame = CGRectMake(8.0, 8.0, w - 16.0, 30.0);
[editButton setFrame:editButtonFrame];
[editButton addTarget:self
action:#selector(editingButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
CGRect headerViewFrame = CGRectMake(0, 0, w, 48);
headerView = [[UIView alloc] initWithFrame:headerViewFrame];
[headerView addSubview:editButton];
return headerView;
}
- (void) editingButtonPressed: (id) sender
{
if( [self isEditing] ) {
[sender setTitle:#"Edit" forState:UIControlStateNormal];
[self setEditing:NO animated:YES];
}
else {
[sender setTitle: #"Done" forState:UIControlStateNormal];
[self setEditing:YES animated:YES];
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [self headerView];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return [[self headerView] frame].size.height;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
Team *t = [teams objectAtIndex:[sourceIndexPath row]];
[teams removeObjectAtIndex:[sourceIndexPath row]];
[teams insertObject:t atIndex:[destinationIndexPath row]];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if( editingStyle == UITableViewCellEditingStyleDelete ) {
[teams removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths: [NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if( editing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
}
else {
/*
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
*/
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numberOfRows = [teams count];
if( [self isEditing] )
numberOfRows++;
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if( !cell ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
if( [indexPath row] < [teams count] ) {
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
}
else {
[[cell textLabel] setText: #"Add New Item ... "];
}
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
return cell;
}
#end
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
this make the table view reload data ..and check the data in its datasource methods..
i believe it is crashing on
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
there might be no objects in the teams array on here for the new index paths...
check by breakpointing here..