I'm working with the EventKit Framework. It is working almost perfect but I have still some issues. When I push my on an Event, it goes to the details of that Event. It shows correctly the details and I can also edit and save it. The problem is with the navigation bar.
It shows the titles inside the navigation bar.These titles are Event Details and Edit. Also it is not showing a backbutton, to go back to my calendar. What I also should mention is that I'm using the Kal Calendar framework.
I'm pushing to de detailsViewController like this.
Appointment *appointment = [dataSource appointmentAtIndexPath:indexPath];
// Upon selecting an event, create an EKEventViewController to display the event.
self.detailViewController = [[EKEventViewController alloc] initWithNibName:nil bundle:nil];
self.detailViewController.title = #"";
detailViewController.event = appointment.event;
// Allow event editing.
detailViewController.allowsEditing = YES;
[calendar.navigationController pushViewController:detailViewController animated:YES];
And this is how my delegate looks like
// Overriding EKEventEditViewDelegate method to update event store according to user actions.
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action {
NSError *error = nil;
EKEvent *thisEvent = controller.event;
controller.title = #"";
switch (action) {
case EKEventEditViewActionCanceled:
// Edit action canceled, do nothing.
break;
case EKEventEditViewActionSaved:
// When user hit "Done" button, save the newly created event to the event store,
// and reload table view.
// If the new event is being added to the default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList addObject:thisEvent];
}
[controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error];
//[calendar reloadData];
break;
case EKEventEditViewActionDeleted:
// When deleting an event, remove the event from the event store,
// and reload table view.
// If deleting an event from the currenly default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList removeObject:thisEvent];
}
[controller.eventStore removeEvent:thisEvent span:EKSpanThisEvent error:&error];
//[calendar reloadData];
break;
default:
break;
}
// Dismiss the modal view controller
[controller dismissModalViewControllerAnimated:YES];
}
// Set the calendar edited by EKEventEditViewController to our chosen calendar - the default calendar.
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller {
EKCalendar *calendarForEdit = self.defaultCalendar;
return calendarForEdit;
}
I came up with this solution:
EKEventEditViewController * controller = [[EKEventEditViewController alloc] init];
controller.eventStore = self.eventStore;
controller.event = result;
controller.title = #"";
controller.navigationItem.title = #"";
controller.navigationItem.titleView = [UIView new];
NSArray * array =controller.navigationBar.items;
UINavigationItem * titleItem = array.firstObject;
titleItem.title = #"";
controller.editViewDelegate = (id)self;
[self presentViewController:controller animated:YES completion:NULL];
The EKEventEditViewController is not embedded in a navigation controller, it has its own UINavigationBar, I keep the navigation item if Apple will change this in the future and embed it in a navigation controller.
i think you have added navigation item on the storyboard or nib file. remove it.
make self.title=nil; or self.title=#"";
Related
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action {
NSError *error = nil;
EKEvent *thisEvent = controller.event;
switch (action) {
case EKEventEditViewActionCanceled:
// Edit action canceled, do nothing.
break;
case EKEventEditViewActionSaved:
// When user hit "Done" button, save the newly created event to the event store,
// and reload table view.
// If the new event is being added to the default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList addObject:thisEvent];
}
[controller.eventStore saveEvent:controller.event span:EKSpanFutureEvents error:&error];
[self.tableView reloadData];
break;
case EKEventEditViewActionDeleted:
// When deleting an event, remove the event from the event store,
// and reload table view.
// If deleting an event from the currenly default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList removeObject:thisEvent];
}
[controller.eventStore removeEvent:thisEvent span:EKSpanFutureEvents error:&error];
[self.tableView reloadData];
break;
default:
break;
}
// Dismiss the modal view controller
[controller dismissModalViewControllerAnimated:YES];
}
this function in the EKEventEditViewDelegate. I want to know when i click which button the "action" value is EKEventEditViewActionDeleted.
at first, I think when I click the delete event button, the action == EKEventEditViewActionDeleted. but not. anyone can help me?
Implement the EKEventViewDelegate protocol then check for the delete event with...
-(void) eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action
{
if (action == EKEventViewActionDeleted) {
// Update unique event ID to core data & change text of button to new
_itemReminder = NULL;
_part.reminderID = NULL;
_savedEventFound = NO;
[_reminderButton setTitle: #"New" forState: UIControlStateNormal];
}
}
I have this code in my Application:
if (self.uiSwtichState == TRUE)
{
if ([CLLocationManager locationServicesEnabled])
{
[self.textString stringByAppendingString:[[[SMSLocationModel alloc] init] getLocation]];
}
}
MFMessageComposeViewController *sms = [[MFMessageComposeViewController alloc] init];
sms.messageComposeDelegate = self;
sms.body = self.textString;
sms.recipients = self.arrayOfNumbers;
[self presentModalViewController:sms animated:YES];
this code is into a method called "send".
As you can imagine, the method getLocation get the current user location and, the first time the Application run, a UIAlertView appear on the screen asking the user if he want to allow the application to get his location.
The problem is that when this UIAlertView appear, she is immediately replaced by the sms Vie Controller (MFMessageComposeViewController) and in this way the user doesn't have enough time for answer YES or NO in the UIAlertView.
There is a way for wait that the user press a button in the UIAlertView and THEN present the ModalViewController?
Thanks!
you could use the CLLocationManagers delegate method to wait until the authorization state changes. Save the sms viewController to an instance variable if you are not authorized to use location services. then ask the location manager to authorize you. If the authorization state changes present that view controller.
// somewhere else
self.locationManager.delegate = self;
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(#"New Authorization State: %d", status);
if (self.viewControllerToPresentAfterLocationDidChange) {
if (status == kCLAuthorizationStatusAuthorized) {
// set location of viewController
[self presentViewController:self.viewControllerToPresentAfterLocationDidChange animated:YES completion:NULL];
}
else {
// user did not authorize you to use location services
}
self.viewControllerToPresentAfterLocationDidChange = nil;
}
}
- (IBAction)buttonPressed:(id)sender {
UIViewController *vc = [[UIViewController alloc] init];
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
// authorized already, no alert will appear.
// set location of vc
[self presentViewController:vc animated:YES completion:NULL];
}
else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
self.viewControllerToPresentAfterLocationDidChange = vc;
// access location so alert will show
}
else {
// not authorized or restricted.
}
}
Maybe you can use this delegate:
- (void)didPresentAlertView:(UIAlertView *)alertView{
}
For example, initializing a boolean which can prevent of presenting this modal view controller. Then if dismissed change the boolean to allow presenting this view controller.
Yes, you can implement the AlertViewDelegate.
See UIAlertViewDelegate Documentation for further information.
Then you can use the alertView:clickedButtonAtIndex: method and present your MessageComposer when the user has clicked the alert view.
on language switch within my App, I need to access the views of the MoreViewController in a TabBar and change their titles.
Could anyone pls tell me how to do that?
Your help is much appreciated.
Cols
Here are some snippets that might work for you. Note that all of the below is subject to break on each and every new iOS release at it is not meant to be done.
Customizing the More view title as itself as well as the title while it is being edited by the user.
- (void)customizeTitleViewWithNavigationItem:(UINavigationItem *)navigationItem
{
VASSERT(navigationItem != nil, #"invalid navigationItem supplied", navigationItem);
UILabel *titleView = [[UILabel alloc] initWithFrame:CGRectZero];
titleView.backgroundColor = [UIColor clearColor];
titleView.font = [UIFont boldSystemFontOfSize:20.0f];
titleView.text = navigationItem.title;
[titleView sizeToFit];
navigationItem.titleView = titleView;
[titleView release];
}
This needs to be implemented within the UINavigationController's delegate;
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if (navigationController == tabBarController_.moreNavigationController)
{
if ([viewController isKindOfClass:NSClassFromString(#"UIMoreListController")])
{
[self customizeTitleViewWithNavigationItem:viewController.navigationItem];
}
else
{
NSLog(#"viewController (%#) does not seem to be a UIMoreListController", viewController);
}
}
else
{
NSLog(#"navigationController (%#) does not seem to be the moreNavigationController", navigationController);
}
}
This needs to be implemented within the UITabBarController's delegate;
- (void)tabBarController:(UITabBarController *)controller willBeginCustomizingViewControllers:(NSArray *)viewControllers
{
//get the second view of the upcoming tabbar-controller
UIView *editView = [controller.view.subviews objectAtIndex:1];
//did we get what we expected, which is a UITabBarCustomizeView?
if (editView != nil && [editView isKindOfClass:NSClassFromString(#"UITabBarCustomizeView")])
{ //yes->get the navigation-view
UIView *navigationView = [editView.subviews objectAtIndex:0];
//is that a navigationBar?
if (navigationView != nil && [navigationView isKindOfClass:[UINavigationBar class]])
{ //yes->...
UINavigationBar *navigationBar = (UINavigationBar *)navigationView;
[self customizeTitleViewWithNavigationItem:navigationBar.topItem];
}
else
{
NSLog(#"the navigationView (%#) does not seem to be a navigationBar", navigationView);
}
}
else
{
NSLog(#"the editView (%#) does not seem to be a UITabBarCustomizeView", editView);
}
}
I was able to change the title of one of the tabBar items for my 6th view controller (the last one in the more list) with the following code:
NSArray *vcs = [(UITabBarController *)self.window.rootViewController viewControllers];
[[vcs.lastObject tabBarItem] setTitle:#"New Title"];
Is this what you want to do?
After Edit: To change these titles after they are set up the first time, you need to re-set the viewControllers property of the tabBar controller. In this code example, I connected a button in my 6th view controller to an action method that changes the titles of 3 of my controllers, 2 in the more list and one in the regular list.
-(IBAction)changeNames:(id)sender {
UITabBarController *tbc = (UITabBarController *)[[UIApplication sharedApplication] delegate].window.rootViewController;
NSArray *vcs = tbc.viewControllers;
[[vcs.lastObject tabBarItem] setTitle:#"New Title"];
[[[vcs objectAtIndex:4] tabBarItem] setTitle:#"New VC"];
[[[vcs objectAtIndex:3] tabBarItem] setTitle:#"New VC2"];
tbc.viewControllers = tbc.viewControllers;
}
i need your help. Basically I created a small scrollView and a pageControl inside my main view controller. Now when ever a button inside a scroll view is pressed I lose the value of every property in my mainViewController. To help you get a clearer picture let me explain:
(NoteViewController.m) This is the action the button that is pressed from the scrollview responds to
- (IBAction)removePerson:(UIButton *)sender {
MainViewController *remover = [[MainViewController alloc] init];
[remover removePersonWithPage:pageNumber];
[self.view removeFromSuperview];
[remover release]; }
(MainViewController.m)
- (void)removePersonWithPage:(int)page {
// The managedObjectContext is lost the moment it leaves MainViewController.m and goes to NoteViewController.m
// so you need to reload the managedObjectContext
if (managedObjectContext == nil)
{
managedObjectContext = [(OrdersAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
// Get the list of people (Persons) from the managed Object Context
arrayOfPeople = [[NSMutableArray alloc] initWithArray:[self fetchDataWithEntity:#"Person" andSortKey:#"pageId"]];
// Find a specific person to delete using their page number and delete it finally remove it from array
NSManagedObject *personToDelete = [arrayOfPeople objectAtIndex:page];
[managedObjectContext deleteObject:personToDelete];
[arrayOfPeople removeObjectAtIndex:page];
// kNumberOfPages is replaced with the new number of people
kNumberOfPages = arrayOfPeople.count;
/* This is where problem occurs */
self.pageControl.numberOfPages = kNumberOfPages;
NSLog(#"The number of pages in the page control in remove is: %d", self.pageControl.numberOfPages);
[self saveObjectContext];
}
So everything works but when I get to the NSLog at the end there, it returns 0 when it ought to be returning the number of pages in the database. I've been working on this for days now and can't figure it out, please help. Thanks
In my appController's ViewDidLoad, I have done some thing as below
- (void)viewDidLoad
{
self.overlayViewController =
[[[OverlayViewController alloc] initWithNibName:#"OverlayViewController" bundle:nil] autorelease];
// as a delegate we will be notified when pictures are taken and when to dismiss the image picker
self.overlayViewController.delegate = self;
self.capturedImages = [NSMutableArray array];
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
// camera is not on this device, don't show the camera button
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:self.myToolbar.items.count];
[toolbarItems addObjectsFromArray:self.myToolbar.items];
[toolbarItems removeObjectAtIndex:2];
[self.myToolbar setItems:toolbarItems animated:NO];
}
}
I have two methods as below,
- (IBAction)cameraAction:(id)sender
{
[self showImagePicker:UIImagePickerControllerSourceTypeCamera];
}
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
if (self.imageView.isAnimating)
self.imageView.stopAnimating;
if (self.capturedImages.count > 0)
[self.capturedImages removeAllObjects];
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
}
}
Now as I click the button, the method will launch the class showing custom view, I want to call this without clicking the button, what should I do ?
I wrote the button coding directly in ViewDidLoad, but not working at all
This code, I took from apple's documentation as example
Help !
If I understand correctly, you are wanting to show a view?
If so you could push using:
[self.navigationcontroller pushviewcontroller:YOURVIEWCONTROLLER animated:YES];
Or you could present it using:
[self presentModalViewControllerpushviewcontroller:YOURVIEWCONTROLLER animated:YES];