I have this:
AddSightingViewController.h
#import <UIKit/UIKit.h>
#class MovieSighting;
#interface AddSightingViewController : UIViewController <UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>
#property (weak, nonatomic) IBOutlet UITextField *movieTitleInput;
#property (weak, nonatomic) IBOutlet UITextField *directorInput;
#property (weak, nonatomic) IBOutlet UITextField *estrenoInput;
#property (strong, nonatomic) MovieSighting *movieSighting;
#end
and this:
AddSightingViewController.m
#import "AddSightingViewController.h"
#import "MovieSighting.h"
#interface AddSightingViewController ()
#property (strong, nonatomic) NSArray *array;
#property (strong, nonatomic) UITextField *genero;
#end
#implementation AddSightingViewController
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ((textField == self.movieTitleInput) || (textField == self.estrenoInput) || (textField == self.directorInput)) {
[textField resignFirstResponder];
}
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *generos = [[NSArray alloc] initWithObjects:#"Drama",#"Fantástico",#"Aventuras",#"Policíaco",#"Romántica",#"Comedia",#"Documental",#"Terror", nil];
self.array = generos;
}
#pragma mark Picker Data Source Methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [_array count];
}
#pragma mark Picker Delegate Methods
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [_array objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString *generoInput = [self.array objectAtIndex:row];
}
//
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReturnInput"]) {
if ([self.movieTitleInput.text length] || [self.directorInput.text length]|| [self.estrenoInput.text length] )
{
MovieSighting *sighting;
NSUInteger *valor = (NSUInteger *)[[self.estrenoInput text] integerValue];
sighting = [[MovieSighting alloc] initWithName:self.movieTitleInput.text anyo:valor genero: director:self.directorInput.text];
self.movieSighting = sighting;
}
}
}
#end
How can I use:
NSString *generoInput = [self.array objectAtIndex:row];
To transform to a property UITextField that I created:
#property (strong, nonatomic) UITextField *genero;
And then use that with the method sighting at the end?
Then I can use it to compare on the method called textFieldShouldReturn.
I´ve been doing that:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString *generoInput = [self.array objectAtIndex:row];
UITextField *nuevo = (UITextField*)[generoInput capitalizedString];
_genero = nuevo;
}
And prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReturnInput"]) {
if ([self.movieTitleInput.text length] || [self.directorInput.text length]|| [self.estrenoInput.text length]
|| [self.genero.text length])
{
MovieSighting *sighting;
NSUInteger *valor = (NSUInteger *)[[self.estrenoInput text] integerValue];
sighting = [[MovieSighting alloc] initWithName:self.movieTitleInput.text anyo:valor genero:self.genero.text director:self.directorInput.text];
self.movieSighting = sighting;
}
}
}
But don´t work the app... Any idea?
When I add other movie and clic on Add:
Appeared that:
Error code:
2013-12-19 21:43:19.875 MovieWatching[920:70b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AddSightingViewController 0x8a63190> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key staticDataSource.'
You want:
self.genero.text = [generoInput capitalizedString];
Related
I am trying to create a setting page for an app that uses Table View Controllers to pass data back changing the detailed text label of the first view controller depending on the text of the selected row of the second Table View Controller. I put a NSLog in under my delegate method on the initial Table View Controller and it is not being called. I am very stuck, any help is greatly appreciated!
Initial VC .h:
// EditAlarmTVC.h (Initial table view controller .h file)
//
#import <UIKit/UIKit.h>
#import "AlarmSoundTVC.h"
#interface EditAlarmTVC : UITableViewController <AlarmSoundDelegate>
#property (weak, nonatomic) IBOutlet UIDatePicker *datePicker;
#property (weak, nonatomic) IBOutlet UITableViewCell *offMethodCell;
#property (weak, nonatomic) IBOutlet UITableViewCell *repeateCell;
#property (weak, nonatomic) IBOutlet UITableViewCell *alarmLabelCell;
#property (weak, nonatomic) IBOutlet UITableViewCell *alarmSoundCell;
#property (strong) NSManagedObjectModel *alarm;
- (IBAction)cancelSetAlarm:(id)sender;
- (IBAction)saveSetAlarm:(id)sender;
#end
Initial VC .m:
//EditAlarmTVC.m (Initial table view controller.m file)
#import "EditAlarmTVC.h"
#import <CoreData/CoreData.h>
#interface EditAlarmTVC ()
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#property (retain, nonatomic) NSMutableArray *detailedTextLabels;
#end
#implementation EditAlarmTVC
#synthesize alarm;
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"offMethod"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"timePicker"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"repeateLabelSoundCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"deleteAlarmCell"];
self.detailedTextLabels =[NSMutableArray array];
[self.detailedTextLabels addObject:#"Off"];
[self.detailedTextLabels addObject:#"Never"];
[self.detailedTextLabels addObject:#"Wake up, get up!"];
[self.detailedTextLabels addObject:#"Default"];
}
-(void) viewWillAppear:(BOOL)animated{
[self.offMethodCell.detailTextLabel setText:[self.detailedTextLabels objectAtIndex:0]];
[self.repeateCell.detailTextLabel setText:[self.detailedTextLabels objectAtIndex:1]];
[self.alarmLabelCell.detailTextLabel setText:[self.detailedTextLabels objectAtIndex:2]];
[self.alarmSoundCell.detailTextLabel setText:[self.detailedTextLabels objectAtIndex:3]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)sendSelection:(NSString *)selectedAlarm{
NSLog(#"hello");
[self.detailedTextLabels replaceObjectAtIndex:3 withObject:selectedAlarm];
[self.myTableView reloadData];
}
-(NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context =nil;
id delegat = [[UIApplication sharedApplication] delegate];
if ([delegat respondsToSelector:#selector(managedObjectContext)]) {
context = [delegat managedObjectContext];
}
return context;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section ==2 & indexPath.row==0){
[self performSegueWithIdentifier:#"repeateSegue" sender:indexPath];
} else if (indexPath.section ==2 & indexPath.row==1){
[self performSegueWithIdentifier:#"alarmLabelSegue" sender:indexPath];
} else if (indexPath.section ==0 & indexPath.row==0){
[self performSegueWithIdentifier:#"offMethodSegue" sender:indexPath];
} else if (indexPath.section ==2 & indexPath.row==2){
[self performSegueWithIdentifier:#"alarmSoundSegue" sender:indexPath];
} else if (indexPath.section ==3 & indexPath.row==0){
//DELETE ALARM
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Alarm" inManagedObjectContext:context];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc]init];
[timeFormatter setDateFormat:#"h:mm"];
NSDate *timeNSDate = [self.datePicker date];
NSString *timeString = [timeFormatter stringFromDate:timeNSDate];
NSDateFormatter *amPmFormatter = [[NSDateFormatter alloc]init];
[amPmFormatter setDateFormat:#"a"];
NSDate *amPmNSDate = [self.datePicker date];
NSString *amPmString = [amPmFormatter stringFromDate:amPmNSDate];
NSPredicate *p1 = [NSPredicate predicateWithFormat:#"time == %#", timeString];
NSPredicate *p2 = [NSPredicate predicateWithFormat:#"amPm == %#", amPmString];
NSPredicate *p3 = [NSPredicate predicateWithFormat:#"offMethod == %#", self.offMethodCell.detailTextLabel.text];
NSPredicate *p4 = [NSPredicate predicateWithFormat:#"repeate == %#", self.repeateCell.detailTextLabel.text];
NSPredicate *p5 = [NSPredicate predicateWithFormat:#"alarmSound == %#", self.alarmSoundCell.detailTextLabel.text];
NSPredicate *p6 = [NSPredicate predicateWithFormat:#"alarmLabel == %#", self.alarmLabelCell.detailTextLabel.text];
NSPredicate *alarmsPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[p1, p2, p3, p4, p5, p6]];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:alarmsPredicate];
NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items)
{
[context deleteObject:managedObject];
}
EditAlarmTVC *goToEditAlarmTVC = [self.storyboard instantiateViewControllerWithIdentifier:#"setAlarmVC"];
[self.navigationController pushViewController:goToEditAlarmTVC animated:YES];
[self dismissViewControllerAnimated:NO completion:nil];
} else
return;
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"alarmSoundSegue"])
{
AlarmSoundTVC *alarmSoundTVC = [[AlarmSoundTVC alloc]init];
[alarmSoundTVC setDelegate:self];
}
}
#end
Second VC .h:
//AlarmSoundTVC.h (Second table view controller .h file)
#import <UIKit/UIKit.h>
#protocol AlarmSoundDelegate <NSObject>
#required
-(void) sendSelection:(NSString *)selectedAlarm;
#end
#interface AlarmSoundTVC : UITableViewController
#property (strong, nonatomic) IBOutlet UITableView *myTableView;
#property (nonatomic, weak) id <AlarmSoundDelegate> delegate;
#end
Second VC .m:
// AlarmSoundTVC.m (Second table view controller .m file)
#import "AlarmSoundTVC.h"
#import "EditAlarmTVC.h"
#interface AlarmSoundTVC ()
#end
#implementation AlarmSoundTVC
- (void)viewDidLoad {
[super viewDidLoad];
self.myTableView.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
NSIndexPath *indexPath = [self.myTableView indexPathForSelectedRow];
UITableViewCell *selectedCell =[self.myTableView cellForRowAtIndexPath:(indexPath)];
NSString *selectedAlarm = selectedCell.textLabel.text;
[self.delegate sendSelection:selectedAlarm] ;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
//- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// }
#end
I am sorry if there is some extra unnecessary code in there. I am a bit new and wanted to be sure I provided plenty of information. Thanks again!
In your prepareForSegue you are setting the delegate on a new, local, instance of AlarmSoundTVC, that will be discarded as soon as the method exits. You need to use the instance that is going to be presented, which can be accessed via the destinationViewController property of the segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"alarmSoundSegue"])
{
AlarmSoundTVC *alarmSoundTVC = (AlarmSoundTVC *)segue.destinationViewController;
[alarmSoundTVC setDelegate:self];
}
}
I'm developing an app in Xcode in Objective-C.
The app has a TableView with an array of restaurants. My problem is that when I try to use the SearchBar I use the Title (name of the restaurant as a filter) but when I show the rows after the filter search, only the Title is right. The other label and the image in the cell is wrong (it shows me the correct title but the image and the other label (description label) is the same as the first row in the original tableview).
I have to change my cellForRowAtIndexPath method but I don't now how to change it.
This is TableViewController called MainTableViewController.h
#import <UIKit/UIKit.h>
#interface MainTableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *barButton;
//#property (nonatomic, strong) NSArray *Images;
//#property (nonatomic, strong) NSArray *Description;
//#property (nonatomic, strong) NSArray *Title;
#property (nonatomic, strong) NSMutableArray *Title;
#property (nonatomic, strong) NSMutableArray *Images;
#property (nonatomic, strong) NSMutableArray *Description;
#property (nonatomic, strong) NSMutableArray *filteredRest;
#property BOOL isFiltered;
#property (strong, nonatomic) IBOutlet UITableView *RestTableView;
#property (strong, nonatomic) IBOutlet UITableView *mySearchBar;
#end
This is my MainTableViewController.c
#import "MainTableViewController.h"
#import "SWRevealViewController.h"
#import "RestTableViewCell.h"
#import "RestViewController.h"
#interface MainTableViewController ()
#end
#implementation MainTableViewController
#synthesize mySearchBar, filteredRest, isFiltered;
- (void)viewDidLoad {
[super viewDidLoad];
_barButton.target = self.revealViewController;
_barButton.action = #selector(revealToggle:);
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
[self.navigationItem setTitle:#"MadEat"]; /*Cambia el titulo del navigation controller*/
[self.navigationController.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}]; /*Cambia el color de las letras del navigation controller bar del menu principal*/
[self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:27/255.0f green:101/255.0f blue:163/255.0f alpha:1.0f]];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; /*Cambia el color del boton de la izquierda*/
self.RestTableView.tableFooterView = [[UIView alloc] init]; /*Esta linea hace que en la tabla solo aparezcan el numero de filas que tienes establecidas, es decir, que las vacias no aparezcan*/
/*Alerta que se muestra solo la primera vez. Está desactivada*/
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"alert"]]) {
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"alert"];
[[NSUserDefaults standardUserDefaults] synchronize];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Terms of use" message:#"The brands mentioned have no relationship with MadEat and the app has no any liability on that content." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"Accept" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
}
_Title = #[#"80 Grados",
#"90 Grados",
#"B&B Babel",
#"Babelia",
#"Bacira",
#"Bar Galleta",
#"Bar Tomate",
#"Barra Atlantica",
#"BaRRa de Pintxos",
#"BaRRa de Pintxos",];
_Description = #[#"Barrio Malasaña",
#"Barrio Retiro",
#"Barrio Chueca",
#"Barrio de Salamanca",
#"Barrio Chamberí",
#"Barrio Malasaña",
#"Barrio Chamberí",
#"Barrio Malasaña",
#"Barrio del Pilar",
#"Barrio Retiro",];
_Images = #[#"80_grados.png",
#"90_grados",
#"babel.png",
#"babelia.png",
#"bacira.png",
#"bar_galleta.png",
#"bar_tomate.png",
#"barra_atlantica.png",
#"barra_de_pintxos.png",
#"barra_de_pintxos.png",];
}
#pragma mark - Table view data source
- (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.
//return _Title.count;
if (isFiltered == YES) {
return filteredRest.count;
} else {
return _Title.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
RestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row];
} else {
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.DescriptionLabel.text = _Description[row];
cell.RestImage.image = [UIImage imageNamed:_Images[row]];
}
cell.RestImage.layer.cornerRadius = 6;
cell.RestImage.clipsToBounds = YES;
cell.RestImage.layer.borderWidth = 1;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
/*Cambia el nombre del boton de la izquierda sin afectar al titulo del navigation controller*/
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle: NSLocalizedString (#"Back", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[segue identifier] isEqualToString:#"ShowDetails"]){
RestViewController *restviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
restviewcontroller.DetailModal = #[_Title[row],_Description[row],_Images[row]];
}
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
//Set our boolean flag
isFiltered = NO;
} else {
//Set our boolean flag
isFiltered = YES;
}
//Alloc and init our filteredData
filteredRest = [[NSMutableArray alloc] init];
for (NSString * restTitle in _Title) {
NSRange restTitleRange = [restTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restTitleRange.location != NSNotFound) {
[filteredRest addObject:restTitle];
}
}
for (NSString * restDescription in _Description) {
NSRange restDescriptionRange = [restDescription rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restDescriptionRange.location != NSNotFound) {
//[filteredRest addObject:restDescription];
}
}
for (NSString * restImages in _Images) {
NSRange restImagesRange = [restImages rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restImagesRange.location != NSNotFound) {
//[filteredRest addObject:restImages];
}
}
//Reload our table view
[_RestTableView reloadData];
}
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[mySearchBar resignFirstResponder];
}
#end
Finally, this is my TableViewCell.h called RestTableViewCell.h
#import <UIKit/UIKit.h>
#interface RestTableViewCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UILabel *DescriptionLabel;
#property (strong, nonatomic) IBOutlet UIImageView *RestImage;
#end
This is my problem graphically:
Obviously, you just apply the filter condition to the Title array, and not filtering the Images and Description array.
So you need to two more NSMutableArray to hold the filtering results for Images and Description.
But I recommend you to build a new Model for your results. Sample code for your reference:
Model layer: Restaurant.h
#interface Restaurant : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *desc;
#property (nonatomic, copy) NSString *image;
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image;
#end
Restaurant.m
#implementation Restaurant
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image {
self = [super init];
if (self != nil) {
self.title = title;
self.desc = description;
self.image = image;
}
return self;
}
#end
RestViewController.h
#interface RestViewController : UIViewController
#property (nonatomic, strong) Restaurant *DetailModal;
#end
MainTableViewController.m
#interface MainTableViewController ()
#property (nonatomic, strong) NSArray<Restaurant *> *originData;
#property (nonatomic, strong) NSMutableArray<Restaurant *> *filteredRest;
#property (nonatomic, assign) Boolean isFiltered;
#end
#implementation MainTableViewController
#synthesize mySearchBar, filteredRest, isFiltered, originData;
- (void)viewDidLoad {
[super viewDidLoad];
originData = #[
[[Restaurant alloc] init:#"80 Grados" descripiton:#"Barrio Malasaña" image:#"80_grados.png"],
[[Restaurant alloc] init:#"90 Grados" descripiton:#"Barrio Retiro" image:#"90_grados"]
];
filteredRest = [NSMutableArray new];
isFiltered = NO;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//return _Title.count;
if (isFiltered == YES) {
return filteredRest.count;
} else {
return originData.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
RestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row].title;
cell.DescriptionLabel.text = [filteredRest objectAtIndex:indexPath.row].desc;
cell.RestImage.image = [UIImage imageNamed:[filteredRest objectAtIndex:indexPath.row].image];
} else {
cell.TitleLabel.text = [originData objectAtIndex:indexPath.row].title;
cell.DescriptionLabel.text = [originData objectAtIndex:indexPath.row].desc;
cell.RestImage.image = [UIImage imageNamed:[originData objectAtIndex:indexPath.row].image];
}
cell.RestImage.layer.cornerRadius = 6;
cell.RestImage.clipsToBounds = YES;
cell.RestImage.layer.borderWidth = 1;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
/*Cambia el nombre del boton de la izquierda sin afectar al titulo del navigation controller*/
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle: NSLocalizedString (#"Back", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[segue identifier] isEqualToString:#"ShowDetails"]){
RestViewController *restviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
if (isFiltered) {
restviewcontroller.DetailModal = filteredRest[myIndexPath.row];
} else {
restviewcontroller.DetailModal = originData[myIndexPath.row];
}
}
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
//Set our boolean flag
isFiltered = NO;
} else {
//Set our boolean flag
isFiltered = YES;
}
//Alloc and init our filteredData
filteredRest = [[NSMutableArray alloc] init];
for (Restaurant *item in originData) {
if ([item.title containsString:searchText]) {
[filteredRest addObject:item];
}
}
//Reload our table view
[self.tableView reloadData];
}
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[mySearchBar resignFirstResponder];
}
#end
With building a new model object for your information is very efficient, so you don't need to apply there filter to three array, you just need to search once, and results will be kept kept in one array.
PS: One more tips for your coding style, naming the variable, object instance with starting lowercase, and naming the class with starting uppercase is best practise when writing OC codes. e.g., TitleLabel should rename to titleLabel, etc...
Here you are filtering cell and reusing them.
You are just replacing text. You need to replace the image and data as well.
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row];
} else {
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.DescriptionLabel.text = _Description[row];
cell.RestImage.image = [UIImage imageNamed:_Images[row]];
}
I am not sure but I think you have not clearly understood concept of reusable cell. You will be reusing cell which are not in the view what that means is iOS framework will give you one of the already used cell so that it doesnt have to recreate cell everytime in your case thats first cell 80Grados.
So, after you receive that cell, you replace the title but leave all other content alone. That is why you see old content with new Title Label.
What you need to do here is create a wrapper class, which will have three properties text, description and imagefile name.
#class Restaurant
#property NSString *title;
#property NString *description;
#property NSString *image;
#end
Combine your logic with this rather than treating all data as separate array. That will be extremely easy to maintain. In future you can easily fill that class with data coming from server, user entered or any otherway. Handling data in 3 different array is not very sustainable model.
So create wrapper class, fill data by creating NSMutableArray/NSMutableDictionary. Rather than putting title, fill entire wrapper object.
[filteredRest addObject: restaurantObj];
And change your code this way
Restaurant *r;
if (isFiltered == YES) {
r = [self.filteredRest objectAtIndex:indexPath.row];
} else {
r = [self.restaurantList objectAtIndex:indexPath.row]];
}
cell.TitleLabel.text = r.title;
cell.DescriptionLabel.text = r.description;
cell.RestImage.image = [UIImage imageNamed:r.image];
Let me know if any of the ideas are not clear. This is just a prototype, you will have to change your code in multiple places but would highly recommend making these changes sooner than later.
When I have my methods formatPhoneNumber/textField methods in my code, it does not allow me to type in any other fields. when I delete them the problem goes away. Can someone show me what is wrong with my code that is causing this problem?
//-------------------------------------------------------------------------------------------------------------------------------------------------
#interface RegisterView()
#property (strong, nonatomic) IBOutlet UITableViewCell *cellName;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellEmail;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellPassword;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellButton;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellPhone;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellFName;
#property (strong, nonatomic) IBOutlet UITableViewCell *cellLName;
#property (strong, nonatomic) IBOutlet UITextField *fieldName;
#property (strong, nonatomic) IBOutlet UITextField *fieldEmail;
#property (strong, nonatomic) IBOutlet UITextField *fieldPassword;
#property (strong, nonatomic) IBOutlet UITextField *fieldPhone;
#property (strong, nonatomic) IBOutlet UITextField *fieldFName;
#property (strong, nonatomic) IBOutlet UITextField *fieldLName;
#end
//-------------------------------------------------------------------------------------------------------------------------------------------------
#implementation RegisterView
#synthesize cellName, cellEmail, cellPassword, cellButton, cellPhone, cellLName, cellFName;
#synthesize fieldName, fieldEmail, fieldPassword, fieldPhone, fieldLName,fieldFName;
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)viewDidLoad
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[super viewDidLoad];
self.title = #"Register";
//UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"giberWallpaper.png"]];
//self.tableView.backgroundColor = background;
self.navigationController.navigationBar.tintColor= [UIColor colorWithRed:(255/256.0) green:(128/256.0) blue:(0/256.0) alpha:(1.0)];
//---------------------------------------------------------------------------------------------------------------------------------------------
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)viewDidAppear:(BOOL)animated
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[super viewDidAppear:animated];
[fieldName becomeFirstResponder];
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)dismissKeyboard
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[self.view endEditing:YES];
}
#pragma mark - User actions
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)actionRegister
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
NSString *name = fieldName.text;
NSString *email = [fieldEmail.text lowercaseString];
NSString *password = fieldPassword.text;
NSString *phoneNumber= fieldPhone.text;
NSString *fName = fieldFName.text;
NSString *lName = fieldLName.text;
NSString *fullName = [NSString stringWithFormat: #"%# %#", fName, lName];
//---------------------------------------------------------------------------------------------------------------------------------------------
if ([name length] < 3) { [ProgressHUD showError:#"Name is too short."]; return; }
if ([email length] == 0) { [ProgressHUD showError:#"Email must be set."]; return; }
if ([password length] == 0) { [ProgressHUD showError:#"Password must be set."]; return; }
if ([phoneNumber length] == 0) { [ProgressHUD showError:#"Phone number must be set."]; return; }
if ([lName length] < 2) { [ProgressHUD showError:#"Name is too short."]; return; }
if ([fName length] < 2) { [ProgressHUD showError:#"Name is too short."]; return; }
//---------------------------------------------------------------------------------------------------------------------------------------------
[ProgressHUD show:#"Please wait..." Interaction:NO];
//---------------------------------------------------------------------------------------------------------------------------------------------
PFUser *user = [PFUser user];
user.email = email;
user.username = email;
user.password = password;
int randInt = arc4random() % 9000 + 1000;
NSString *strInt = [NSString stringWithFormat:#"%d",randInt];
user[PF_USER_PIN] = strInt;
user[PF_USER_NICKNAME] = name;
user[PF_USER_FIRSTNAME] = fName;
user[PF_USER_LASTNAME] = lName;
user[PF_USER_PHONENUMBER] = phoneNumber;
user[PF_USER_EMAILCOPY] = email;
user[PF_USER_FULLNAME] = fullName;
user[PF_USER_FULLNAME_LOWER] = [fullName lowercaseString];
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (error == nil)
{
ParsePushUserAssign();
PostNotification(NOTIFICATION_USER_LOGGED_IN);
[ProgressHUD showSuccess:#"Succeed."];
[self dismissViewControllerAnimated:YES completion:nil];
}
else [ProgressHUD showError:error.userInfo[#"error"]];
}];
}
-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar {
if(simpleNumber.length==0) return #"";
// use regex to remove non-digits(including spaces) so we are left with just the numbers
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error];
simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:#""];
// check if the number is to long
if(simpleNumber.length>10) {
// remove last extra chars.
simpleNumber = [simpleNumber substringToIndex:10];
}
if(deleteLastChar) {
// should we delete the last digit?
simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1];
}
// 123 456 7890
// format the number.. if it's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d+)"
withString:#"($1) $2"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
else // else do this one..
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:#"(\\d{3})(\\d{3})(\\d+)"
withString:#"($1) $2-$3"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
return simpleNumber;
}
- (BOOL)textField:(UITextField *)fieldPhone shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* totalString = [NSString stringWithFormat:#"%#%#",self.fieldPhone.text,string];
// if it's the phone number textfield format it.
if(self.fieldPhone.tag==102 ) {
if (range.length == 1) {
// Delete button was hit.. so tell the method to delete the last char.
self.fieldPhone.text = [self formatPhoneNumber:totalString deleteLastChar:YES];
} else {
self.fieldPhone.text = [self formatPhoneNumber:totalString deleteLastChar:NO ];
}
return false;
}
return YES;
}
#pragma mark - Table view data source
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
return 1;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
return 7;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
if (indexPath.row == 0) return cellName;
if (indexPath.row == 1) return cellFName;
if (indexPath.row == 2) return cellLName;
if (indexPath.row == 3) return cellPhone;
if (indexPath.row == 4) return cellEmail;
if (indexPath.row == 5) return cellPassword;
if (indexPath.row == 6) return cellButton;
return nil;
}
#pragma mark - Table view delegate
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//---------------------------------------------------------------------------------------------------------------------------------------------
if (indexPath.row == 6) [self actionRegister];
}
#pragma mark - UITextField delegate
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (BOOL)textFieldShouldReturn:(UITextField *)textField
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
if (textField == fieldName)
{
[fieldFName becomeFirstResponder];
}
if (textField == fieldFName)
{
[fieldLName becomeFirstResponder];
}
if (textField == fieldLName)
{
[fieldPhone becomeFirstResponder];
}
if (textField == fieldPhone)
{
[fieldEmail becomeFirstResponder];
}
if (textField == fieldEmail)
{
[fieldPassword becomeFirstResponder];
}
if (textField == fieldPassword)
{
[self actionRegister];
}
return YES;
}
#end
Change fieldPhone to textField in your shouldChangeCharactersInRange: method, it's conflicting with your local declaration of the UITextField fieldPhone.
You'll also need to update all the references in that method to the new textField. So your new method will look like this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string.
I'm trying to build a screen with two dependent components in a picker view. I connected picker with property, dataSource and delegate with yellow button of view controller on the top of the scene, and I also connected button action with buttonPressed method.
After building I receive white screen with empty picker without data. Why does it happen?
#import "BIDDependentComponentPickerViewController.h"
#define kStateComponent 0
#define kZipComponent 1
#interface BIDDependentComponentPickerViewController ()
#property (strong, nonatomic) NSDictionary *stateZips;
#property (strong, nonatomic) NSArray *states;
#property (strong, nonatomic) NSArray *zips;
#property (weak, nonatomic) IBOutlet UIPickerView *dependentPicker;
#end
#implementation BIDDependentComponentPickerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:#"statedictionary"
withExtension:#"plist"];
self.stateZips = [NSDictionary dictionaryWithContentsOfURL:plistURL];
NSArray *allStates = [self.stateZips allKeys];
NSArray *sortedStates = [allStates sortedArrayUsingSelector:
#selector(compare:)];
self.states = sortedStates;
NSString *selectedState = self.states[0];
self.zips = self.stateZips[selectedState];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
}
- (IBAction)buttonPressed:(id)sender {
NSInteger stateRow = [self.dependentPicker
selectedRowInComponent:kStateComponent];
NSInteger zipRow = [self.dependentPicker
selectedRowInComponent:kZipComponent];
NSString *state = self.states[stateRow];
NSString *zip = self.zips[zipRow];
NSString *title = [[NSString alloc] initWithFormat:
#"You selected zip code %#.", zip];
NSString *message = [[NSString alloc] initWithFormat:
#"%# is in %#", zip, state];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component == kStateComponent) {
return [self.states count];
} else {
return [self.zips count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if (component == kStateComponent) {
return self.states[row];
} else {
return self.zips[row];
}
}
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
if (component == kStateComponent) {
NSString *selectedState = self.states[row];
self.zips = self.stateZips[selectedState];
[self.dependentPicker reloadComponent:kZipComponent];
[self.dependentPicker selectRow:0
inComponent:kZipComponent
animated:YES];
} }
#end
Make sure you have added statedictionary file in bundle.
Also you can Log the array/dictionary to check if values are there.
I'm seeing a gradual build up of memory that I think might be a retain cycle.
When does this happen: Click on a custom cell that expands and injects a nib with 3 buttons into the expanded area. Clicking the cell again closes the cell, shrinks the cell's tablerow height, rotates an open indicator and removes the previously injected nib.
If I open and close the cell multiple times I see the memory gradually building up.
Any ideas what might be causing this would be greatly appreciated.
Sorry I don't have enough reputation to post photos.
Build up:
Example of retained objects(mostly Animation related):
EDIT: Using ARC and on iOS 6
MasterViewController - TableView Functions
#pragma mark - UITABLEVIEW
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.topicsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier2 = #"SRCollapsibleCellClosed";
SRCollapsibleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[SRCollapsibleCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
SRTopic *topic = [self.topicsArray objectAtIndex:indexPath.row];
[cell updateWithTopic:topic];
if([self isCellOpen:indexPath]){
CGAffineTransform transformation = CGAffineTransformMakeRotation(M_PI/2);
cell.arrow.transform = transformation;
if(![self hasChoiceBox:cell]){
[self insertChoiceBox:cell atIndex:indexPath];
}
} else{
CGAffineTransform transformation = CGAffineTransformMakeRotation(0);
cell.arrow.transform = transformation;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([self isCellOpen:indexPath]){
[self closeCellAtIndexPath:indexPath];
}
else{
NSIndexPath * openCell= self.openCellIndex;
NSIndexPath * newOpenCell= indexPath;
[self closeCellAtIndexPath:openCell];
[self openCellAtIndexPath:newOpenCell];
}
[tableView beginUpdates];
[tableView endUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
-(CGFloat)tableView: (UITableView*)tableView heightForRowAtIndexPath: (NSIndexPath*) indexPath {
if([indexPath isEqual:self.openCellIndex]){
return 217.0;
} else {
return 63.0;
}
}
-(void)rotateCellArrowAtIndexPath:(NSIndexPath*)indexPath willOpen:(bool)willOpen Animated:(bool)animated{
// Change Arrow orientation
SRCollapsibleCell *cell = (SRCollapsibleCell*) [self.topicsTableView cellForRowAtIndexPath:indexPath];
CGAffineTransform transformation;
if(willOpen){
transformation = CGAffineTransformMakeRotation(M_PI/2);
} else {
transformation = CGAffineTransformMakeRotation(0);
}
if(animated){
[UIView animateWithDuration:.2 delay:0 options:nil animations:^{
cell.arrow.transform = transformation;
} completion:nil];
}
else{
cell.arrow.transform = transformation;
}
}
-(BOOL)isCellOpen:(NSIndexPath *)indexPath{
return [indexPath isEqual:self.openCellIndex];
}
-(void)closeCellAtIndexPath:(NSIndexPath*)indexPath{
//NSLog(#"Cell closing");
[self rotateCellArrowAtIndexPath:indexPath willOpen:NO Animated:YES];
[self removeSRChoiceBoxFromCellAtIndexPath:indexPath];
self.openCellIndex = nil;
}
-(void)openCellAtIndexPath:(NSIndexPath*)indexPath{
[self rotateCellArrowAtIndexPath:indexPath willOpen:YES Animated:YES];
SRCollapsibleCell *cell = (SRCollapsibleCell*)[self.topicsTableView cellForRowAtIndexPath:indexPath];
[self insertChoiceBox:cell atIndex:indexPath];
self.openCellIndex = indexPath;
}
-(void)removeSRChoiceBoxFromCellAtIndexPath:(NSIndexPath *)indexPath{
SRCollapsibleCell *cell = (SRCollapsibleCell*) [self.topicsTableView cellForRowAtIndexPath:indexPath];
for(id subview in cell.SRCollapsibleCellContent.subviews){
if([subview isKindOfClass:[SRChoiceBox class]]){
SRChoiceBox *tempBox = subview;
[tempBox removeFromSuperview];
tempBox.delegate = nil;
tempBox = nil;
}
}
}
-(void)insertChoiceBox: (SRCollapsibleCell *)cell atIndex:(NSIndexPath *) indexPath
{
//SRChoiceBox *newBox = [[SRChoiceBox alloc] initWithFrame:CGRectMake(0, 0, 310, 141)];
SRChoiceBox *newBox = [[SRChoiceBox alloc] init];
SRTopic *topic = [self.topicsArray objectAtIndex:indexPath.row];
[newBox updateWithSRTopic:topic];
newBox.delegate = self;
[cell.SRCollapsibleCellContent addSubview:newBox];
cell = nil;
topic = nil;
newBox = nil;
}
-(bool)hasChoiceBox:(SRCollapsibleCell *)cell{
for(UIView *subview in cell.SRCollapsibleCellContent.subviews){
if([subview isKindOfClass:[SRChoiceBox class]]){
return true;
}
}
return false;
}
SRChoiceBox - UIView object that gets inserted into cell
//.h
#protocol SRChoiceBoxDelegate <NSObject>
-(void)positionWasChoosen: (NSString *)choice topicId: (NSNumber *)topicId;
#end
#interface SRChoiceBox : UIView
-(id) initWithLabel: (NSDictionary *)labels andTopicID: (NSNumber *)topicId andFrame:(CGRect)frame;
#property (nonatomic, weak) IBOutlet UIView *SRChoiceBox;
#property (nonatomic, strong) NSNumber *SRTopicId;
#property (nonatomic, weak) id<SRChoiceBoxDelegate> delegate;
#property (weak, nonatomic) IBOutlet UILabel *agreeCount;
#property (weak, nonatomic) IBOutlet UILabel *disagreeCount;
#property (weak, nonatomic) IBOutlet UILabel *observeCount;
-(IBAction)buttonPress:(id)sender;
-(void)updateWithSRTopic:(SRTopic *)topic;
....
//.m
-(id)init{
self = [super init];
if (self) {
UINib *nib = [UINib nibWithNibName:#"SRChoiceBox" bundle:nil];
NSArray *q = [nib instantiateWithOwner:self options:nil];
[self addSubview:q[0]];
}
return self;
}
-(void)updateWithSRTopic:(SRTopic *)topic
{
self.SRTopicId = topic.topicId;
self.agreeCount.text = [NSString stringWithFormat: #"%#",topic.agreeDebaters];
self.disagreeCount.text = [NSString stringWithFormat: #"%#",topic.disagreeDebaters];
self.observeCount.text = [NSString stringWithFormat: #"%#",topic.observers];
}
- (IBAction)buttonPress:(id) sender {
int tag = [sender tag];
switch (tag) {
case 0:
[self.delegate positionWasChoosen:#"agree" topicId:self.SRTopicId];
break;
case 1:
[self.delegate positionWasChoosen: #"disagree" topicId:self.SRTopicId];
break;
case 2:
[self.delegate positionWasChoosen: #"observe" topicId:self.SRTopicId];
break;
default:
break;
}
}
- (void)dealloc
{
self.SRChoiceBox =nil;
self.SRTopicId=nil;
self.delegate=nil;
self.agreeCount=nil;
self.disagreeCount=nil;
self.observeCount=nil;
//NSLog(#"choicebox deallocated: %#", self);
}
SRCollapsibleCell -- Reusable cell
//.h
#interface SRCollapsibleCell : UITableViewCell
#property (strong) NSNumber *topicId;
#property (strong) NSDictionary *topicStats;
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UILabel *subtitle;
#property (weak, nonatomic) IBOutlet UILabel *agreeDebaters;
#property (weak, nonatomic) IBOutlet UILabel *disagreeDebaters;
#property (weak, nonatomic) IBOutlet UILabel *observers;
#property (weak, nonatomic) IBOutlet UIImageView *arrow;
#property (weak, nonatomic) IBOutlet UIView *SRCollapsibleCellContent;
//-(void)updateWithTopic:(NSDictionary *) stats;
-(void)formatTitle:(NSString *)title;
-(void)updateWithTopic: (SRTopic *)topic;
#end
//.m
#implementation SRCollapsibleCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(void)formatTitle:(NSString *)title{
if(title.length<30){
self.title.text= title;
self.subtitle.text =#"";
} else {
NSArray *splitString = [self splitString:title maxCharacters:30];
self.title.text = splitString[0];
self.subtitle.text = splitString[1];
splitString = nil;
title = nil;
}
}
////http://www.musicalgeometry.com/?p=1197
- (NSArray *)splitString:(NSString*)str maxCharacters:(NSInteger)maxLength {
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:1];
NSArray *wordArray = [str componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSInteger numberOfWords = [wordArray count];
NSInteger index = 0;
NSInteger lengthOfNextWord = 0;
while (index < numberOfWords && tempArray.count<2) {
NSMutableString *line = [NSMutableString stringWithCapacity:1];
while ((([line length] + lengthOfNextWord + 1) <= maxLength) && (index < numberOfWords)) {
lengthOfNextWord = [[wordArray objectAtIndex:index] length];
[line appendString:[wordArray objectAtIndex:index]];
index++;
if (index < numberOfWords) {
[line appendString:#" "];
}
}
[tempArray addObject:line];
NSMutableString *subtitle = [NSMutableString stringWithCapacity:1];
while(index<numberOfWords){
[subtitle appendString:[wordArray objectAtIndex:index]];
[subtitle appendString:#" "];
index++;
}
[tempArray addObject:subtitle];
break;
}
return tempArray;
}
//Breaks MVC but it makes the MasterVC cleaner
-(void)updateWithTopic: (SRTopic *)topic
{
[self formatTitle:topic.title];
self.topicId = topic.topicId;
self.agreeDebaters.text = [NSString stringWithFormat:#"%#",topic.agreeDebaters];
self.disagreeDebaters.text = [NSString stringWithFormat:#"%#", topic.disagreeDebaters];
self.observers.text = [NSString stringWithFormat:#"%#", topic.observers];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
#end