THX FOR THE HELP!
I changed the Viewdidload like that and it is working fine for me now! Iam Fetching the location and took a predicate to synchronize the checks and the state of the button
- (void)viewDidLoad
{
[super viewDidLoad];
app = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [app managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Standort" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ortcheck CONTAINS YES"];
[request setPredicate:predicate];
[request setEntity:entity];
NSError *error = nil;
NSArray *events = [context executeFetchRequest:request error:&error];
int i = events.count;
if (i == 0) {
myWeiter = [[UIBarButtonItem alloc] initWithTitle:#"Weiter" style:UIBarButtonItemStyleBordered target:self action:#selector(nextPressed:)];
self.navigationItem.rightBarButtonItem = myWeiter;
self.navigationItem.rightBarButtonItem.enabled = NO;
}
else {
myWeiter = [[UIBarButtonItem alloc] initWithTitle:#"Weiter" style:UIBarButtonItemStyleBordered target:self action:#selector(nextPressed:)];
self.navigationItem.rightBarButtonItem = myWeiter;
self.navigationItem.rightBarButtonItem.enabled = YES;
}
Add a check counter as an instance member, and initialize it to 0, on each check increase it, and on each uncheck decrease it, after each check set the button:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// snip
//if (cell.checkButton.hidden==YES){
// cell.checkButton.hidden=NO;
//}else {
// cell.checkButton.hidden=YES;
//}
BOOL state = !cell.checkButton.hidden;
cell.checkButton.hidden=state; // simpler
self.counter += (state) ? 1 : -1;
[nextButton setEnabled: counter > 0];
// snap
}
Related
Here, m try to sort the array when refersh the tableview but is crash the application when refresh tableview.
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[_PFArray
sortUsingDescriptors:]: unrecognized selector sent to instance
0x6080000550c0'
#interface TableViewController () {
NSMutableArray *returnArray;
}
#end
- (void)viewDidAppear:(BOOL)animated {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate manageObjectContext];
NSError *error = nil;
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Resgistration" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:#"Unique",nil]];
returnArray = [[NSMutableArray alloc] init];
returnArray = [context executeFetchRequest:request error:&error];
for(Resgistration* reg in returnArray) {
NSLog(#"%#", reg);
NSLog(#"%#", reg.roshan);
}
[self.tableView reloadData];
UIColor *gray = [UIColor colorWithRed:234/255.0 green:234/255.0 blue:234/255.0 alpha:1.0];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Please Wait"];
[refreshControl setBackgroundColor:gray];
[refreshControl addTarget:self action:#selector(sortArray) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
}
- (void)sortArray
{
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES selector:#selector(localizedStandardCompare:)];
NSMutableArray *sortDescriptior = [[NSMutableArray alloc] initWithObjects:sort, nil];
[returnArray sortUsingDescriptors:sortDescriptior]; // crash the app
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
Please help me to fix this problem. Thank you.
_PFArray is a subclass of NSArray and is immutable. You can use sortUsingDescriptors: on mutable array only, hence the crash.
It looks like somewhere along the code you have assigned instance of CoreData array inside returnArray variable. There you must use mutableCopy method to convert the immutable array to its mutable version, something like this:
returnArray = [<data array fetched from core data> mutableCopy];
Edit after looking at complete code
returnArray = [[context executeFetchRequest:request error:&error] mutableCopy];
I have a screen which shows favourite locations and if a user wants to add new location he can search using uisearchcontroller and add it to favourite location's list.
The problem is that once i make the api call for autocomplete the list of searched locations is visible but i cannot select or scroll the table.
I know that the problem is where i set the uisearchcontroller. but i do not know the right way to do it.
I am newbie in iOS so ur suggestions will be welcome.
the following is the GithubRepository for the project(incase ul want to try out the app and make suggestions)
and heres the related code where i beleive the problem exists.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
favList = [[NSMutableArray alloc] init];
searchList = [[NSMutableArray alloc]init];
self.table.dataSource = self;
self.table.delegate = self;
[self initSearch];
}
#pragma mark UI Search methods
-(void) initSearch
{
FavouriteViewController *searchResultsController = [[FavouriteViewController alloc] init];
searchResultsController.table.dataSource = self;
searchResultsController.table.delegate = self;
searchResultsController.table.allowsSelectionDuringEditing = YES;
searchResultsController.table.allowsSelection = YES;
self.search = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
self.definesPresentationContext = NO;
self.table.tableHeaderView = self.search.searchBar;
self.search.searchResultsUpdater = self;
self.search.searchBar.delegate = self;
self.search.dimsBackgroundDuringPresentation = NO;
}
didSelectRowAtIndex method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.search.active) {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObjectModel *place = [NSEntityDescription insertNewObjectForEntityForName:#"Place" inManagedObjectContext:context];
NSString *places =[searchList[indexPath.row] valueForKey:#"name"];
if (![favList containsObject:places])
{
NSString *lati = [searchList[indexPath.row] valueForKey:#"lat"];
NSString *longi = [searchList[indexPath.row] valueForKey:#"lon"];
if (places != NULL && lati != NULL && longi != NULL)
{
[place setValue:places forKey:#"placeName"];
[place setValue:lati forKey:#"latitude"];
[place setValue:longi forKey:#"longitude"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
[self.search setActive:NO];
filtered = NO;
[self getalldata];
[self.table reloadData];
}
else
{
NSManagedObject *device = [favList objectAtIndex:indexPath.row];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.SJI.Weather-App"];
[defaults setObject:[device valueForKey:#"placeName"] forKey:#"favSet"];
[[self navigationController] popToRootViewControllerAnimated:YES];
}
}
Hello i am using UISerchbar in tableview but is there any easy way to create custom searchbar in tableview headerview?
i already check below link but i am not understand.
Custom UISearchBar with UISearchController
How do I use the UISearchBar and UISearchDisplayController
I have added searchDisplayController : :
And This is my code for searchController,
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.definesPresentationContext = YES;
[self.searchController.searchBar setBarTintColor:[UIColor darkGrayColor]];
self.tableView.tableHeaderView = self.searchController.searchBar;
I have set delegate for UISearchBarDelegate,UISearchResultsUpdating as well,
and implemented their method ,
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
if (_searchController.isActive && _searchController.searchBar.text.length >0){
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF.name contains[cd] %#",
searchText];
abcd = [sortedEventArray filteredArrayUsingPredicate:resultPredicate];
NSLog(#"%#",searchResults);
}
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController1
{
NSString *searchString = searchController1.searchBar.text;
[self filterContentForSearchText:searchString scope:#"abc"];
//[self filterContentForSearchText:searchString :#"abc"];
[self.tableView reloadData];
}
cancel button event
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
abcd=[sortedEventArray mutableCopy];
[_tableView reloadData];
}
-(void)delete{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest * allMovies = [[NSFetchRequest alloc] init];
[allMovies setEntity:[NSEntityDescription entityForName:#"Data" inManagedObjectContext:context]];
[allMovies setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSError * error = nil;
NSArray * movies = [context executeFetchRequest:allMovies error:&error];
//error handling goes here
for (NSManagedObject * movie in movies) {
[context deleteObject:movie];
}
NSError *saveError = nil;
[context save:&saveError];
}
Still Its not working
Thanks in advance :)
There is everythings is complete but there is two little mistakes by me.
1) delete the search bar from Storyboard.
2) Add [self.searchController.searchBar sizeToFit];
in viewDidLoad
Thanks :))
I have a method in ViewController.m called getData which is called inside viewDidLoad:
-(void)getData {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"WorkoutHasExercise" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = [NSArray arrayWithObjects:#"exerciseName", #"reps", #"sets", nil];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(workoutName = %#)", _workoutName];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
} else {
[_exercises removeAllObjects];
for (int x = 0; x < [objects count]; x++) {
matches = objects[x];
[_exercises addObject:[matches valueForKey:#"exerciseName"]];
[_totalSets addObject:[matches valueForKey:#"sets"]];
[_totalReps addObject:[matches valueForKey:#"reps"]];
[_currentSets addObject:[NSNumber numberWithInteger:0]];
}
}
[_exercisesTableView reloadData];
}
I also have a custom UITableViewCell with two buttons initiated in cellForRowAtIndexPath:
ActiveWorkoutCell *cell = (ActiveWorkoutCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ActiveWorkoutCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.increaseButton.tag = indexPath.row;
cell.decreaseButton.tag = indexPath.row;
In ActiveWorkoutCell.m I have 2 IBActions for the buttons:
- (IBAction)decreaseSets:(id)sender {
ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
[vc decreaseSets:[sender tag]];
}
- (IBAction)increaseSets:(id)sender {
ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
[vc increaseSets:[sender tag]];
}
The IBActions call these 2 methods back in ViewController.m
-(void)increaseSets:(NSInteger)row {
[self getData];
//There will be code here to increase the value of currentSets[row]
}
-(void)decreaseSets:(NSInteger)row {
[self getData]
//Code to decrease value...
}
PROBLEM:
When getData is called from viewDidLoad, it works fine.
The problem occurs when returning to ViewController.m from the IBAction in ActiveWorkoutCell.m.
When I call [self getData] in increaseSets the fetch request returns an empty array. This is what is confusing me - the code works fine when it is first called but not at all when called the second time after the custom cell Action has been triggered.
Here is my viewDidLoad if it helps:
- (void)viewDidLoad {
[super viewDidLoad];
_exercises = [NSMutableArray array];
_totalSets = [NSMutableArray array];
_currentSets = [NSMutableArray array];
_totalReps = [NSMutableArray array];
_titleLabel.text = _workoutName;
_exercisesTableView.allowsSelection = NO;
[self getData];
}
_workoutName is given a value in prepareForSegue in the previous view controller.
I think I found the issue. You are instantiating the "ActivityWorkOutViewController" when the IBAction methods called and it will be a new instance and then in those methods you are calling [self getData] which pointing to the new instance which has no variables instantiated or viewDidLoad happened, so your mutable arrays are not allocated and hence they are empty.
Just use the old instance of the class to get the data.
I am not sure how you are referencing those classes. I am just in a confusion about that. But, you might check the allocations and calling the right class to get the data
I have a very weird problem related to adding a NSMangedObject to a one-many relationship, where only one object gets added, even though I try to add multiple objects to the relationship.
I have to following setup:
When I add a product object to the ProductCart entity, I use the following code:
+ (ProductCart *)addProductToCartWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {
ProductCart *cartProduct = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"ProductCart"];
request.predicate = [NSPredicate predicateWithFormat:#"name = %#", cartProduct.name];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || ([matches count] > 1)) {
// handle error
} else if ([matches count] == 0) {
cartProduct = [NSEntityDescription insertNewObjectForEntityForName:#"ProductCart" inManagedObjectContext:context];
[product addChosedProductsObject:cartProduct];
} else {
cartProduct = [matches lastObject];
}
return cartProduct;
}
this then returns a productCart object I can add to my (one) Cart. I do this like so:
+ (Cart *)addProductToCartWithProduct:(ProductCart *)cartProduct inManagedObjectContext:(NSManagedObjectContext *)context;
{
Cart *cart = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Cart"];
NSError *error = nil;
NSArray *carts = [context executeFetchRequest:request error:&error];
if (!carts || ([carts count] > 1)) {
} else if (![carts count]) {
cart = [NSEntityDescription insertNewObjectForEntityForName:#"Cart" inManagedObjectContext:context];
} else {
cart = [carts lastObject];
}
if (cartProduct && cart) {
[cart addProductsObject:cartProduct];
}
return cart;
}
In my viewcontroller which is showing all the products then passes the cart object to my cart Viewcontroller like so:
-(void)addProductToOrder:(UIButton *)sender {
NSIndexPath *ip = [NSIndexPath indexPathForRow:sender.tag inSection:0];
Product *product = (Product *)[self.fetchedResultsController objectAtIndexPath:ip];
NSInteger amount = product.quantity.intValue;
amount++;
product.quantity = [NSNumber numberWithInt:amount];
UITabBarController *tabBarController = self.tabBarController;
for (UINavigationController *navController in tabBarController.viewControllers) {
for (UIViewController *vc in navController.viewControllers) {
if ([vc isMemberOfClass:NSClassFromString(#"CartViewController")]){
CartViewController *cVC = (CartViewController *) vc;
ProductCart *prodCart = [ProductCart addProductToCartWithProduct:product inManagedObjectContext:self.theManagedObjectContext];
Cart *cart = [Cart addProductToCartWithProduct:prodCart inManagedObjectContext:self.theManagedObjectContext];
cVC.cart = cart;
}
}
}
BOOL saved = [self saveCurrentContext:self.theManagedObjectContext];
if (saved) {
[self addToCartTapped:ip];
[self.menuDetailTableView reloadData];
}
}
-(BOOL)saveCurrentContext:(NSManagedObjectContext *)context {
BOOL contextSaved = NO;
NSError *error;
BOOL saved = [context save:&error];
// [[DataManager sharedInstance] saveBackgroundContext];
// [[DataManager sharedInstance] saveMasterContext];
if (saved) {
contextSaved = YES;
}else {
[self displayErrorAlert:error];
}
return contextSaved;
}
the cart that is passed, is then fetched like so in another viewcontroller (cartviewcontroller) like so:
- (void)loadCart {
[self.theManagedObjectContext reset];
if (self.cart) {
NSFetchRequest *fetchRequest;
if (!fetchRequest) {
fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:#"ProductCart" inManagedObjectContext:self.theManagedObjectContext];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"inCart = %#", self.cart];
}
NSSortDescriptor *sortDescriptor;
if (!sortDescriptor) {
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"products.name" ascending:YES];
fetchRequest.sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
}
if (!self.fetchedResultsController) {
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController.delegate = self;
}
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
[self displayErrorAlert:error];
}
}
self.cartProducts = self.fetchedResultsController.fetchedObjects;
}
But for some reason only one object (product) gets added to the cart, even tough i try to added multiple objects, I think there is something wrong with my add addProductToCartWithProduct: method, when I try to add the objects to the relationship.
What am I doing wrong and how can I fix this, so I can add multiple objects to the relationship?