UITableView requires double tap - but not first time - ios

I have an UITableView, with cells that you can tap on.
When you tap, some actions are run, but that is not important in this context. First time I press, it handles the tap correctly. Second time it is running the code, but all View updates like showing a UIAlertView or showing a new view is delayed. But not delayed by time - It's waiting for me to touch the screen. No matter where I press or how long I wait, I just have to press. And it's every time but the first.
My TableView is set to single selection and not to show selection on touch. Any Ideas why it does this?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[DetailTableViewCell class]]) {
DetailTableViewCell *detailCell = (DetailTableViewCell *)cell;
NSString *hourString = [detailCell hourString];
if (!detailCell.booking) {
NSDate *rightNow = [NSDate new];
NSDate *cellDate = [self.currentDate dateWithHour:indexPath.row andMinutes:0];
// Only allow future bookings (but allow people people to book within the hour)
if([rightNow compare:[cellDate nextHour]] == NSOrderedAscending){
[self performSegueWithIdentifier:#"roomBooking" sender:indexPath];
return;
} else {
[[[UIAlertView alloc] initWithTitle:#"Error" message:#"We currently do not allow our users make bookings in the past" delegate:nil cancelButtonTitle:#"Gotcha" otherButtonTitles:nil] show];
return;
}
} else if ([detailCell.booking hasPhoneNumber]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"telprompt://%ld",(long)[detailCell.booking telephone]]]];
return;
} else {
//TODO: FIND OUT IF BOOKING IS OWNED BY THE CURRENT USER
[[[UIAlertView alloc] initWithTitle:#"Booking"
message:[NSString stringWithFormat:#"You are now removing the booking at %#.", hourString]
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
#weakify(self);
[self.room removeBookingWithId:[detailCell.booking.bookingId integerValue] andCompletion:^(BOOL success, NSError *error) {
#strongify(self);
if (success) {
#weakify(self);
[self.room.location updateBookingsWithCompletion:^(BOOL success, NSError *error) {
#strongify(self);
if (success) {
[self.calendar reloadData];
}
}];
}
}];
return;
}
}
}

SelectionStyle was set to None, but we changed it to something else, which solved the problem.
Click on the TableViewCell itself.
In your properties section locate: "Selection"
Set to: Blue/Grey/Default.

Related

Tableview And MBProgressHUD not loading objects

So i have this piece of code in my TVC
-(void)getCats {
[HUD showAnimated:YES whileExecutingBlock:^{
catArray = [menuPost getCategories];
} completionBlock:^{
if(catArray == nil){
[[[UIAlertView alloc] initWithTitle:#"Oops!" message:#"Hubo un problema intente mas tarde" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil] show];
}
}];
}
i placed some break points and i noticed that i doesn't execute the method right away it jumps to
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return catArray.count;
}
so the problem is that since it skips this line of code(below) the numberOfRows is 0 and this method returns an NSMutableArray after making a post it wouldn't display the objects
catArray = [menuPost getCategories];
your code is fine , you are not refresh your table
-(void)getCats {
[HUD showAnimated:YES whileExecutingBlock:^{
catArray = [menuPost getCategories];
} completionBlock:^{
if(catArray == nil){
[[[UIAlertView alloc] initWithTitle:#"Oops!" message:#"Hubo un problema intente mas tarde" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil] show];
// if your array count ==0 , hidden the table
[yourtableviewname setHidden:YES];
}
else
{
// if your array count !=0 , open the table, and reload/refresh the table
[yourtableviewname setHidden:NO];
[yourtableviewname reloadData];
}
}];
}

HMAccessoryDelegates not calling on Button action

I am working on Homekit iOS app. I have a question that I have an accessory and When I change its power characteristic value using the HomeKit Simulator the delegates of HMAccessory are caliing but in case If I change the powr characteristic value programmatically (Using the writevalue ) the delegate methods are not being called. Please let me know any ideas of suggestions.
Code
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
selectedDevice.delegate = self;
}
HMAccessoryDelegate
- (void)accessory:(HMAccessory *)accessory service:(HMService *)service didUpdateValueForCharacteristic:(HMCharacteristic *)characteristic;
{
NSLog(#"changed");
}
Write Function
UISwitch *sw = [[UISwitch alloc] initWithFrame:CGRectMake(230, 5, 51, 31)];
[cell addSubview:sw];
sw.on = YES;
[sw addTarget:self action:#selector(updateState:) forControlEvents:UIControlEventValueChanged];
-(void)updateState:(UISwitch*)sender
{
HMCharacteristic *characteristic = self.selectedService.characteristics[tag];
[characteristic enableNotification:YES completionHandler:^(NSError *error)
{
if(!error)
{
}
}];
if([characteristic.characteristicType isEqualToString:HMCharacteristicTypePowerState])
{
id val = characteristic.value;
NSString *str = [NSString stringWithFormat:#"%#",val];
if([str isEqualToString:#"0"])
{
id a = characteristic.value;
BOOL b = [a boolValue];
NSNumber *c = [NSNumber numberWithBool:!b];
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
[characteristic writeValue:c completionHandler:^(NSError *error) {
if (error) {
UIAlertView *alertController = [[UIAlertView alloc] initWithTitle:#"Error" message:[appDel handleErrorCodes:error.code] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertController show];
return;
}
else
{
[serviceCharacteristicsTableView reloadData];
}
}];
}
}
Please let me know if I am not clear
The documentation says that the delegate method is not called when you set the value programatically:
This method is called as a result of a change in value initiated by
the accessory. Programmatic changes initiated by the app do not result
in this method being called.
If you want to do something after writing the characteristic's value succeeded (or failed), you can do it in the completionHandler: block of writeValue:completionHandler: method.

Call when clicked on tableview cell

I'm making a UITableView where you can click on a tableviewcell and this should trigger a phone call to a phone number in an array.
The phone numbers are listed in an array, and these are also shown in the tableviewcell.
_Number = #[#"100",
#"101",
#"070 245 245"];
I'm new at this and I don't know how to start with this, I already got my tableviewcontroller and tableviewcell classes which are working.
Gratz and thanks in advance
You can do following :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *phoneNumber = [Number objectAtIndex:indexPath.row];
NSURL *phoneNumberURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", phoneNumber]];
if( [[UIApplication sharedApplication] canOpenURL:phoneNumberURL] )
{
[[UIApplication sharedApplication] openURL:phoneNumberURL];
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert!!!" message:#"Not able to make a phone call." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}

UITableViewController table won't refresh after deletion, but will refresh on viewWillAppear

I have a button for each cell, and once clicked it deletes each individual object from the Parse backend. I have it set to reloadData upon success in the block as seen here:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
PFRelation *relation = [self.currentUser relationforKey:#"watching"];
[[relation query] findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
// There was an error
} else {
// NSLog(#"%#", objects);
self.watchingEvents = objects;
[self refreshTableView];
}
}];
}
-(IBAction) deleteButtonAction:(id) sender
{
[SVProgressHUD showWithStatus:#"Removing from Watch List..."];
PFRelation *relation = [self.currentUser relationforKey:#"watching"];
[relation removeObject:self.selectedEvent];
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error)
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlertView show];
}
else
{
[SVProgressHUD showSuccessWithStatus:#"Removed from Watch List!"];
[self refreshTableView];
}
}];
}
-(void)refreshTableView
{
[self.tableView reloadData];
}
But it doesn't seem to update the tableView, the cell still shows up (even though it's gone because if I navigate away and open the view again the viewWillAppear gets called with the same reloadData function and the items gone like how it should be. So I know the functions working, since it's clearly working in viewWillAppear. Not sure why it's not working once the success of the block is run, as the alert runs fine as does any NSLog message I put in?
Change you refresh method to:
-(void)refreshTableView
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
you are deleting the data from the backend but you are not deleting that object from self.watchingEvents. and i think u must be using self.watchingEvents to populate the date in cellForRowAtindex of your table. Please delete that object from self.watchingEvents too on deletion and your problem should be solved.
You need to use [tableView beginUpdates] before you do delete, insert or move actions and then [tableView endUpdates] at the end.
- (void)beginUpdates;
- (void)endUpdates;
https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/beginUpdates

App crashed after enable or disable calendar from settings

I have implemented EKEventStore, EKCalendar in my app to make the EKEvent within the app. It is working fine until or unless I didn't change permissions from the settings. But when I changed the requested access (on/off or off/on) from the settings, the app get crashed. I am unable to find the error. If someone has idea then please help me out. Here is the code I have implemented :
self.eventStore = [[EKEventStore alloc] init];
[self checkEventStoreAccessForCalendar];
-(void)checkEventStoreAccessForCalendar
{
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
break;
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Privacy Warning" message:#"Permission was not granted for Calendar"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
} }
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,
NSError *error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
-(void)accessGrantedForCalendar
{
self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents;
EKEvent *addEvent = [EKEvent eventWithEventStore:self.eventStore];
addEvent.title = [NSString stringWithFormat:#"%#", textcontainer.text];
}
#pragma mark EKEventEditViewDelegate
-(void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action{
[self dismissViewControllerAnimated:YES completion:^
{
if (action != EKEventEditViewActionCanceled)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller
{
return self.defaultCalendar;
}
When your app goes to the background it should save all its states and should be prepared to get killed. When someone switches off access to calendar, the easiest way for the system to deals with that is to kill your app, and that is why its happening. If you switch back to your app by clicking 'Back to Your-App' on top, you can notice that your app will be launching from the beginning, not from where you left. Try not using the breakpoint and you will notice the change.
So its not a crash actually.

Resources