I have a TableViewController subclass with one prototype cell designed in storyboard. Then I am passing the references to the class header etc and for some reason it fails to compile it. But the connections seem fine. I provide you the code and pictures of the build errors and the storyboard. I am using Xcode 4.3.3. Any help is really appreciated.
favTable.h
#import <UIKit/UIKit.h>
#interface favTable : UITableViewController <NSFetchedResultsControllerDelegate>
{
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
NSArray *favArr;
NSMutableArray *favName;
NSMutableArray *favScore;
}
#property (nonatomic, retain) NSArray *favArr;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong) NSMutableArray *favName;
#property (nonatomic, strong) NSMutableArray *favScore;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
#property (strong, nonatomic) IBOutlet UITableViewCell *celldes;
#property (strong, nonatomic) IBOutlet UIImageView *cellimage;
#property (strong, nonatomic) IBOutlet UILabel *cellname;
#property (strong, nonatomic) IBOutlet UILabel *cellmanu;
#property (strong, nonatomic) IBOutlet UILabel *cellscore;
#end
favTable.m
#import "favTable.h"
#import "ecoAppDelegate.h"
#interface favTable ()
#end
#implementation favTable
#synthesize favArr;
#synthesize managedObjectContext;
#synthesize fetchedResultsController;
#synthesize favName;
#synthesize favScore;
#synthesize celldes;
#synthesize cellimage;
#synthesize cellname;
#synthesize cellmanu;
#synthesize cellscore;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Favorites";
self.navigationController.navigationBar.translucent = NO;
// passing the array of addedtofavorites to the total one with all favorites
self.managedObjectContext = ((ecoAppDelegate *) [UIApplication sharedApplication].delegate).managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"FavoritesInfo" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.resultType = NSDictionaryResultType;
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:#"name", nil]];
NSError *error=nil;
self.favArr=[[self.managedObjectContext executeFetchRequest:fetchRequest error:&error]mutableCopy];
if (error!=nil) {
NSLog(#" fetchError=%#,details=%#",error,error.userInfo);
}
self.favName = [[self.favArr valueForKey:#"name"] mutableCopy];
self.favScore = [[self.favArr valueForKey:#"score"] mutableCopy];
}
- (void)viewDidUnload
{
[self setCelldes:nil];
[self setCellimage:nil];
[self setCellname:nil];
[self setCellmanu:nil];
[self setCellscore:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [favName count];;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
// Configure the cell...
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cellname.text = #"Test";
return cell;
}
#end
I moved manually the IB outlets into a separate custom cell class and then linked the references to the storyboard (maybe this is fixed in newer versions)
Then applied that cell style in the prototype cell and simply changed the content of the UI items of my cell using the identifier (no tag was needed)
Related
I want to present a UItableViewController when a button is press using popoverPresentationController.
It works ok if the device is not rotated, but if the device is rotated the preferredContentSize it is not ok.
The code:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
#import "ViewController.h"
#import "TableViewController.h"
#interface ViewController () <UIAdaptivePresentationControllerDelegate>
#end
#implementation ViewController
- (IBAction)showActionButtonPress:(id)sender {
TableViewController *tableViewController = [[self storyboard] instantiateViewControllerWithIdentifier:#"TableViewController"];
tableViewController.modalPresentationStyle = UIModalPresentationPopover;
tableViewController.popoverPresentationController.sourceView = sender;
tableViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown;
UIPresentationController *presentationController = tableViewController.presentationController;
presentationController.delegate = self;
tableViewController.preferredContentSize = CGSizeMake(414.0, 174.0);
[self presentViewController:tableViewController animated:YES completion:nil];
}
#pragma mark - <UIAdaptivePresentationControllerDelegate>
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller{
NSLog(#"%#: %#", NSStringFromSelector(_cmd), self);
return UIModalPresentationNone;
}
#end
#import <UIKit/UIKit.h>
#interface TableViewController : UITableViewController
#end
#import "TableViewController.h"
#import "TableViewCell.h"
#implementation TableViewController
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
// return 210;
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//return UITableViewAutomaticDimension;
return 174.0;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"%#: %#", NSStringFromSelector(_cmd), self);
NSString *CellIdentifier = #"CellIdentifier";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.imageView.image = [UIImage imageNamed:#"ball.png"];
cell.label1.text = #"One";
cell.label2.text = #"Two";
cell.label3.text = #"Three";
cell.label4.text = #"Four";
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#end
#import <UIKit/UIKit.h>
#interface TableViewCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIImageView *cellImageView;
#property (nonatomic, strong) IBOutlet UILabel *label1;
#property (nonatomic, strong) IBOutlet UILabel *label2;
#property (nonatomic, strong) IBOutlet UILabel *label3;
#property (nonatomic, strong) IBOutlet UILabel *label4;
#end
#import "TableViewCell.h"
#implementation TableViewCell
#end
Image Portrait:
Image LandScape:
I have implemented a application in which I use NSTableview with the help of its data source and delegates I have not used NSArrayController nor I want to use it. My question is how can I bind NSSearchField with my NSTableView in this situation? I had seen a lot of answer using NSArrayController.
I do not want to convert implementation to NSArrayController as things are working good with NSMutableArray.
TableView is a display control and is not for filtering.
You should add 2 NSArray properties;
1) #property(nonatomic, strong) NSArray *allItems;
2) #property(nonatomic, strong) NSArray *filteredItems;
#import "ViewController.h"
#interface ViewController()<NSSearchFieldDelegate, NSTableViewDelegate, NSTableViewDataSource>
// Your NSSearchField
#property (weak) IBOutlet NSSearchField *searchField;
// Your NSTableView
#property (weak) IBOutlet NSTableView *tableView;
// In this array you will store all items
#property(nonatomic, strong) NSArray *allItems;
// In this array you will store only filtered items
#property(nonatomic, strong) NSArray *filteredItems;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.searchField.delegate = self;// You can set delegate from XIB/Storyboard
self.tableView.delegate = self;// You can set delegate from XIB/Storyboard
self.tableView.dataSource = self;// You can set dataSource from XIB/Storyboard
self.allItems = #[#"Test1", #"Demo filter", #"Test 2", #"Abracadabra"];
[self applyFilterWithString:#""];
}
- (void)controlTextDidChange:(NSNotification *)obj{
if (obj.object == self.searchField) {
[self applyFilterWithString:self.searchField.stringValue];
}
}
-(void)applyFilterWithString:(NSString*)filter {
if (filter.length>0) {
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", filter];
self.filteredItems = [self.allItems filteredArrayUsingPredicate:filterPredicate];
}
else {
self.filteredItems = self.allItems.copy;
}
[self.tableView reloadData];
}
#pragma mark - ***** NSTableViewDataSource, NSTableViewDelegate *****
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return self.filteredItems.count;
}
// for the "Cell Based" TableView
- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row {
NSString *item = self.filteredItems[row];
return item;
}
#end
my program always an error of threads.
error that appears at compile time
http://imgur.com/6rGkwKd
1. My .h
import
#interface PerfilViewController : UIViewController
<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property (weak, nonatomic) IBOutlet UIImageView *fotoPerfil;
#property (weak, nonatomic) IBOutlet UIButton *botaoSalvarFoto;
#property (nonatomic) UIImagePickerController *pegarFoto;
-(IBAction)salvarFoto:(UIButton *)sender;
#end
2. My .m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
_pegarFoto = [[UIImagePickerController alloc]init];
_pegarFoto.delegate = self;
_pegarFoto.sourceType = UIImagePickerControllerSourceTypeCamera;
}
-(IBAction)salvarFoto:(UIButton *)sender {
[self presentViewController:_pegarFoto animated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
_fotoPerfil.image = img;
[[picker parentViewController] dismissViewControllerAnimated:YES completion:nil];
}
I have done this on another project before and got it working then, but I cannot find out why this piece of my programming will not work.
It displays the table without any of the plist data on it.
Please take a look through my code to see if you can spot where I have made a mistake, thanks.
#import "MarketViewController.h"
#import "SecondViewController.h"
#import "ECSlidingViewController.h"
#import "MenuViewController.h"
#interface MarketViewController ()
#end
#implementation MarketViewController
#synthesize shares, shareValues, number, shareName;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
self.navigationItem.title = #"Stock Market";
NSString *sharesFile = [[NSBundle mainBundle] pathForResource:#"Shares" ofType:#"plist"];
shares = [[NSDictionary alloc] initWithContentsOfFile: sharesFile];
shareValues = [shares objectForKey:#"Share Values"];
shareName = [shares objectForKey:#"Share Names"];
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.layer.shadowOpacity = 0.75f;
self.view.layer.shadowRadius = 10.0f;
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Menu"];
}
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
self.menuBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_menuBtn.frame = CGRectMake(8, 10, 34, 24);
[_menuBtn setBackgroundImage:[UIImage imageNamed:#"menuButton.png"] forState:UIControlStateNormal];
[_menuBtn addTarget:self action:#selector(revealMenu:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.menuBtn];
}
//Table View
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [shares count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString *cellIdentifier = #"cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
NSString *nameOfShare = [shareName objectAtIndex:[indexPath row]];
NSString *valueOfShare = [shareValues objectAtIndex:[indexPath row]];
cell.detailTextLabel.text = valueOfShare;
cell.textLabel.text = nameOfShare;
return cell;
self.title = #"Stock Market";
}
- (IBAction)revealMenu:(id)sender
{
[self.slidingViewController anchorTopViewTo:ECRight];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
My h. file is as follows:
#import <UIKit/UIKit.h>
#interface MarketViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) UIButton *menuBtn;
#property (nonatomic, readonly) NSDate *CurrentDate;
#property (nonatomic, strong) NSDictionary *shares;
#property (nonatomic, strong) NSArray *shareValue;
#property (nonatomic, strong) NSArray *number;
#property (nonatomic, strong) NSArray *shareName;
- (NSString*)filePath;
- (void)openDB;
#end
I am having a real problem finding where my problem is in my search controller. This is a table view with search bar and search display controller. It used to work fine, but all the sudden it stopped working. I turned on NSZombieEnabled and it shows that my NSArray called searchDataSource is the zombie.
When you type a search term the "shouldReloadTableForSearchTerm" executes the handleSearchForTerm function. The handleSearchForTerm" function accesses my ProductInfo class that query a SQLite database and returns the query results. Those results are then placed in my searchDataSource Array. Everything appears to work fine there. However, once I get to the "cellForRowAtIndexPath" function and I try to load the cells from the searchDataSource, that is when I run in to the problem of the Array having been deallocated.
Here is my code for the search controller:
//
// SearchViewController.h
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FourthViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate> {
UITableView *mainTableView;
NSArray *searchDataSource;
NSMutableArray *contentsList;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
NSString *webURL;
}
#property (nonatomic, retain) IBOutlet UITableView *mainTableView;
#property (nonatomic, retain) IBOutlet NSArray *searchDataSource;
#property (nonatomic, retain) NSMutableArray *contentsList;
#property (nonatomic, retain) NSMutableArray *searchResults;
#property (nonatomic, copy) NSString *savedSearchTerm;
#property (nonatomic, retain) NSString *webURL;
- (void)handleSearchForTerm:(NSString *)searchTerm;
#end
SearchViewController.m
//
// SearchViewController.m
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import "FourthViewController.h"
#import "ProductsDatabase.h"
#import "ProductInfo.h"
#import "WebViewController.h"
#implementation FourthViewController
#synthesize mainTableView;
#synthesize searchDataSource;
#synthesize contentsList;
#synthesize searchResults;
#synthesize savedSearchTerm;
#synthesize webURL;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.searchDataSource count];
}
- (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] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set up the cell...
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row]; //This is where I get the 'message sent to deallocated instance' message.
[cell.textLabel setText:info.sName];
[cell.detailTextLabel setText:info.sType];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row];
webURL = [NSString stringWithFormat:#"http://www.prioritywire.com/specs/%#", info.sFile];
WebViewController *wvController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]];
wvController.URL = webURL;
wvController.navTitle = #"Spec Sheet";
[self.navigationController pushViewController:wvController animated:YES];
[wvController release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (void)dealloc {
[searchDataSource release], searchDataSource = nil;
[mainTableView release];
[contentsList release];
[searchResults release];
[savedSearchTerm release];
[super dealloc];
}
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
} else {
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self contentsList])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self handleSearchForTerm:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[self setSavedSearchTerm:nil];
self.searchDataSource = nil;
[self.mainTableView reloadData];
}
#end
I am quite new to objective-C and can't understand what I did wrong. I have spent days trying to figure this out and have had no luck. I would appreciate any help anyone can offer.
Keith
This bit of code seems to be the only place searchDataSource gets set:
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
If ProductsDatabase follows the rules, you don't own the returned array (i.e. it is already autoreleased) so the release on the fourth line is incorrect.
Don't you mean to use your searchResults-array instead of your searchDataSource, because in handleSearchForTerm: you are adding the results to it. Why do you even have the searchResult ivar? It's only used in handleSearchForTerm:, maybe some mixup there?