Wednesday, 13 April 2016

UI Sizes & Layouts

UI Sizes & Layouts

3D Touch

A key new feature in iOS 9 is called 3D Touch, allowing people to quickly access options inside and outside of your app.
Users can now force-press your App Icon and find frequently used items. Inside an app, mails can be peeked and links can be previewed before entering full-screen.Think of 3D Touch like the keyboard shortcuts on your Mac – they enable people to do repeated tasks quicker. You have to design shortcuts that make power users more productive. But just like Keyboard shortcuts, essential features shouldn’t be exclusive to 3D Touch. Your users must be able to operate your app normally without it.

Points and Pixels

Developers work with point values, so it is important to understand the difference with pixels. When the iPhone was first introduced, the two units were the same: 1pt equals 1px. Then when retina screens came along, 1pt became 2px. So think of points as the values in the original iPhone, and pixels as the real values depending on the pixel density (iPhone 4,5,6 = @2x, iPhone 6 Plus = @3x).

iPhone Resolutions

The iPhone has 4 main resolutions: 320 x 480 pt (iPhone 4), 320 x 568 pt (iPhone 5), 375 x 667 pt (iPhone 6) and414 x 736 pt (iPhone 6 Plus). The layout doesn’t scale but expands based on the resolution. For example, the Navigation Bar only adjusts the width but keeps the same height. Elements inside it remain intact.
The iPhone 6 Plus is the only iPhone that acts more like an iPad in Landscape mode. In other words, a Left Navigation will appear, replacing the need for the Tab Bar.

iPad Resolutions

The iPad has 2 main resolutions: 768 x 1024 pt (iPad),1024 x 1366 pt (iPad Pro).
The iPad has 2 new features: Slide Over and Split View.Slide Over is an overlay that appears on the right of the screen without affecting the current app’s layout.
Split View allows users to multitask by running 2 apps simultaneously next to each other in Portrait mode.

App Icon

The App Icon is used for the branding of your app. It’s the first thing that users see when they experience it. It appears prominently on the Home screen, the App Store, in Spotlight and Settings.

@1x assets are no longer supported for the iPhone, so you don’t need to generate them. App icons have 2 resolutions now: @2x and @3x. There are 3 types: App Icon, Spotlight and Settings. For the iPad, @1x and @2x are used.

Super-Ellipse

Since iOS 7, the rounded corners have shifted from plain rounded corners to a super-ellipse shape. It is important to keep note that you shouldn’t export the icons with the mask, or you’ll potentially find black artifacts. Instead, just export square assets to the App Store.

Icon Grid

Apple applied a golden ratio on some of their icons. This ensures that the icons are the heroes while keeping good proportions. While this is a good rule to follow, it’s not a strict rule. Even Apple omitted it on many of their icons.

Colors

iOS uses vibrant colors to bring out the buttons. These colors tend to work well against a white background as much as a black background. Keep in mind that colors should be used sparsely, for call-to-actions and minimal branding areas like the navigation bar. Roughly, only 10-20% of your design should have colors, or they will compete too much against the content.
iOS often uses neutral colors to serve as the background and menu areas. A well-contrasted black text against a white background is used to make the text comfortable to read. Finally, the pastel blue is applied for making the buttons stand out.

Button and Font Sizes

The general rule is 44pt for buttons and 12pt for small text,17pt for body text and 20pt+ for titles.

Spacing and Alignment

A general rule is to have a minimum padding or margin of8pt. This creates enough breathing room, which makes the layout easier to scan and the text more readable. Also, UI elements should be aligned and texts should have the same baseline position.

Status Bar

It is recommended to include the status bar in as many places as you can. Users rely on it for important information such as signal, time and battery. The text and icons can be white or black, but the background can be customized into any color and merge with the Navigation Bar.

Navigation Bar

The Navigation Bar is used for quick information about the screen. The left portion can be used for placing Back,ProfileMenu buttons whereas the right portion is generally used for action buttons like AddEditDone. Note that if you use any of these system icons, you don’t need to create assets for them.
Just like the Status Bar, the background can be customized to any color and typically has a subtle blur to ensure that the text is always readable. When the Status Bar is present, both backgrounds are merged.

Search Bar

When you have a lot of content, it is always wise to make it searchable.

Toolbar

When you need more real estate to place your action buttons and screen status, you’ll want to use the Toolbar.

Tab Bar

The Tab Bar is the main navigation between multiple screens. if you have few items. Menus that are always visible will increase usage since obvious Always Win. Additionally, it is encouraged to add text next to your icons as most people won’t instantly recognize symbols, especially when they’re not universally known.
When they’re not active, icons will generally have an outline instead of being filled. Like this, they attract less attention.

Table View

The Table View is a very common user interface for listing content. Most apps use a form of Table View. That’s because it can be very basic, or highly customizable down to the smallest elements.
At the basic level, you can use a number of preset Styles and Accessories.
Cells can also be grouped, with a title above and description underneath.

Collection View

When you have both rows and columns in a grid style, you’ll need the Collection View. Although a little more advanced, it can pretty much create any layout you can dream of.
Collection View layouts may look like these, or a combination of them. The possibilities are endless.

Modals

The Alert dialog is used for conveying critical information and prompting quick actions. Alerts should be kept minimal and exiting must be obvious.
The Activity dialog allows you to share content (text, images, links) to iOS features like Airdrop, Favorites, Bookmarks and apps like Mail, Facebook, Twitter. While the look can’t be customized, the options are.
When the information presented isn’t short, you can design a modal that is full-sized, typically appearing from a slide, fade, flip or page animation. Like other modals, it must be easy to cancel and kept as short as possible.

Keyboards

The keyboard is used to input information in text fields such as search, chat or login. It’s highly customizable, for URL, Email, Phone numbers and even Emoji. You can choose between the Light and Dark themes, as well as how the action button is named (return being the default).

Picker

When you have multiple options to choose from, you can use the Picker control. It’s particularly useful for dates, which controls 3 fields in one action.

Segmented Control

While the Tab Bar navigates to the main sections, the Segmented Control is used for sub-sections.

Sliders

Sliders are interactive controls that are less precise, but extremely useful for quick settings like Sound, Brightness and Video Progress.

Progress

The Progress bar is an indicator showing how far an activity has gone. For example, you can use this to show the loading progress of a Web View. Note that the height can be customized.

Switch

Use this to quickly toggle between on and off. Do not use this for anything else than on / off.

Stepper

Slower but more precise than the Slider, the Stepper allows the user to increase or decrease a value by an increment of one. The border and background are customizable.

iOS Icons

These are the native icons that permeate iOS. Since they’re commonly used, they’re instantly recognized by users for their meaning. Using them for other purposes may confuse your users, so it’s important to be aware of how they’re used in iOS.
When you design custom icons outside of these, it is important to use well-known symbols. Additionally, I strongly recommend to always accompany them with a small text of 10pt or more.

Resources

These templates are not only useful for study but also to re-use and customize, so you don't have to start from scratch and open the possibility for errors. As you get more comfortable with them, you’ll be able to get creative.

iOS 9 GUI for iPhone

If you're designing for iOS, you'll want to use pre-made elements such as the status, navigation and tab bars. Get comfortable with all the colors, sizes, fonts and components.

iOS 9 GUI for iPad

The new iPad UI Kit features the iPad Pro device and keyboards in both portrait and landscape modes. Everything is in vector.

Apple Watch GUI

A very complete UI Kit for the Apple Watch with very element including the Apple Watch devices, icons and clocks in vector. You can resize and export them at any resolution.




Saturday, 9 April 2016

Custom Calender

Custom Calender




1)  Write Following Code In NSObject :


* NSObject ( Get Method For add & Remove Event ) 

MyCalendar.h :



#import <Foundation/Foundation.h>

@interface MyCalendar : NSObject


+ (void)requestAccess:(void (^)(BOOL granted, NSError *error))success;
+ (BOOL)addEventAt:(NSDate*)eventDate withEndDate:(NSDate*)endDate withTitle:(NSString*)title inLocation:(NSString*)location latitude: (NSString*)latval longitude:(NSString*)longval ;
+ (BOOL)removeEventAt:(NSDate*)eventDate withEndDate:(NSDate*)endDate withTitle:(NSString*)title inLocation:(NSString*)location;



@end



MyCalendar.m :


#import "MyCalendar.h"
#import <EventKit/EventKit.h>

#import "SQLManager.h"


static EKEventStore *eventStore = nil;
static NSString *savedEventId;

@implementation MyCalendar



+ (void)requestAccess:(void (^)(BOOL granted, NSError *error))callback;
{
    if (eventStore == nil) {
        eventStore = [[EKEventStore alloc] init];
    }
    // request permissions
    [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:callback];
}


+ (BOOL)addEventAt:(NSDate*)eventDate withEndDate:(NSDate*)endDate withTitle:(NSString*)title inLocation:(NSString*)location latitude: (NSString*)latval longitude:(NSString*)longval ;
{
    EKEvent *event = [EKEvent eventWithEventStore:eventStore];
    EKCalendar *calendar = nil;
    NSString *calendarIdentifier = [[NSUserDefaults standardUserDefaults] valueForKey:@"my_calendar_identifier"];

    // when identifier exists, my calendar probably already exists
    // note that user can delete my calendar. In that case I have to create it again.
    if (calendarIdentifier) {
        calendar = [eventStore calendarWithIdentifier:calendarIdentifier];
    }
    
    // calendar doesn't exist, create it and save it's identifier
    if (!calendar) {
        calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
        
        // set calendar name. This is what users will see in their Calendar app
        [calendar setTitle:@"My Calendar"];
       
           if (calendar.source == nil)
        {
            for (EKSource *source in eventStore.sources)
            {
                
                if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"])
                {
                    if([source calendarsForEntityType:EKEntityTypeEvent].count>0)
                    {     //Check to see if Calendar is enabled on iCloud
                        
                        NSLog(@"iCloud Calendar is Enabled."); //Calendar is Enabled
                        calendar.source = source;
                        
                    }else
                    {
                        
                        NSLog(@"iCloud Calendar is Disabled."); //Calendar is Disabled
                        
                        if (source.sourceType == EKSourceTypeLocal)
                        {
                            calendar.source = source;
                            break;
                        }
                        
                    }
                    
                    break;
                }
                
                else if (source.sourceType == EKSourceTypeLocal)
                {
                    calendar.source = source;
                    break;
                }
            }
        }


        
        // save this in NSUserDefaults data for retrieval later
        NSString *calendarIdentifier = [calendar calendarIdentifier];
        
        NSError *error = nil;
        BOOL saved = [eventStore saveCalendar:calendar commit:YES error:&error];
        if (saved) {
            // saved successfuly, store it's identifier in NSUserDefaults
            [[NSUserDefaults standardUserDefaults] setObject:calendarIdentifier forKey:@"my_calendar_identifier"];
        } else {
            // unable to save calendar
            return NO;
        }
    }
    
    // this shouldn't happen
    if (!calendar) {
        return NO;
    }
    
    // assign basic information to the event; location is optional
        event.calendar = calendar;
        event.location = location;
        event.title = title;


    // set the start date to the current date/time and the event duration to two hours
        NSDate *startDate = eventDate;
        event.startDate = startDate;
        event.endDate =  endDate;
    
        //event.endDate = [startDate dateByAddingTimeInterval:3600 * 2];
    
    EKStructuredLocation* structuredLocation = [EKStructuredLocation locationWithTitle:location];  // locationWithTitle has the same behavior as event.location
    CLLocation *mylocation = [[CLLocation alloc] initWithLatitude:[latval floatValue] longitude:[longval floatValue]];
    structuredLocation.geoLocation = mylocation;
    
    [event setValue:structuredLocation forKey:@"structuredLocation"];
    
    SQLManager *sqlObj = [[SQLManager alloc] init];
    
    [sqlObj createAndOpenDatabase] ;
    
    [[sqlObj getAllUserInfo] valueForKey:@"alertValue"] ;
    
    NSLog(@"%@",[[sqlObj getAllUserInfo] valueForKey:@"alertValue"]);
    
    if (![[[sqlObj getAllUserInfo] valueForKey:@"alertValue"] isEqualToString:@"0"] && ![[[sqlObj getAllUserInfo] valueForKey:@"alertValue"] isEqualToString:@"4"])
    {
        if ([[[sqlObj getAllUserInfo] valueForKey:@"alertValue"] isEqualToString:@"1"])
        {
            
            NSLog(@"%@", event.startDate);
            NSLog(@"%@", eventDate);
            
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"HH:mm"];
            
            NSString *endTimeString = [formatter stringFromDate:event.startDate];
            
            NSDateFormatter *df = [[NSDateFormatter alloc] init] ;
            [df setDateFormat:@"HH:mm"];
            NSDate *date1 = [df dateFromString:endTimeString];
            NSDate *date2 = [df dateFromString:@"08:00"];
            NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
            
            int hours = (int)interval / 3600;
            int minutes = (interval - (hours*3600)) / 60;
            
            NSString *timeDiff = [NSString stringWithFormat:@"%d:%02d", hours, minutes];
            
            NSLog(@"%f",interval);
            
            NSLog(@"%@",timeDiff);
            
            EKAlarm *enterAlarm = [EKAlarm alarmWithRelativeOffset:interval];
            
            [enterAlarm setProximity:EKAlarmProximityEnter];
            
            [enterAlarm setStructuredLocation:structuredLocation];
            
            [event addAlarm:enterAlarm];
            
            event.alarms = [NSArray arrayWithObject:enterAlarm];

        }
        else if ([[[sqlObj getAllUserInfo] valueForKey:@"alertValue"] isEqualToString:@"2"])
        {
        
            NSTimeInterval interval = 60*120* -1;
            
            EKAlarm *enterAlarm = [EKAlarm alarmWithRelativeOffset:interval];
            
            [enterAlarm setProximity:EKAlarmProximityEnter];
            
            [enterAlarm setStructuredLocation:structuredLocation];
            
            event.alarms = [NSArray arrayWithObject:enterAlarm];
        
        }
        else if ([[[sqlObj getAllUserInfo] valueForKey:@"alertValue"] isEqualToString:@"3"])
        {
            
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"HH:mm"];
            
            NSString *endTimeString = [formatter stringFromDate:event.startDate];
            
            NSDateFormatter *df = [[NSDateFormatter alloc] init] ;
            [df setDateFormat:@"HH:mm"];
            NSDate *date1 = [df dateFromString:endTimeString];
            NSDate *date2 = [df dateFromString:@"08:00"];
            NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
            
            int hours = (int)interval / 3600;
            int minutes = (interval - (hours*3600)) / 60;
            
            NSString *timeDiff = [NSString stringWithFormat:@"%d:%02d", hours, minutes];
            
            NSLog(@"%f",interval);
            
            NSLog(@"%@",timeDiff);
            
            EKAlarm *enterAlarm = [EKAlarm alarmWithRelativeOffset:interval];
            
            [enterAlarm setProximity:EKAlarmProximityEnter];
            
            [enterAlarm setStructuredLocation:structuredLocation];
            
            [event addAlarm:enterAlarm];
            
            NSTimeInterval interval1 = 60*120* -1;
            
            EKAlarm *enterAlarm1 = [EKAlarm alarmWithRelativeOffset:interval1];
            
            [enterAlarm1 setProximity:EKAlarmProximityEnter];
            
            [enterAlarm1 setStructuredLocation:structuredLocation];
            
            [event addAlarm:enterAlarm1];
            
            event.alarms = [NSArray arrayWithObjects:enterAlarm,enterAlarm1, nil];
            
            
        }
        
    }
   
    NSError *error = nil;
    
    BOOL result = [eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&error];
    
    if (result) {
        if ([event respondsToSelector:@selector(calendarItemIdentifier)]) {
            [[NSUserDefaults standardUserDefaults] setObject:event.eventIdentifier forKey:title];
            NSLog(@"Event ID: %@",event.calendarItemIdentifier);
        }
        return YES;
    } else {
       // [[NSUserDefaults standardUserDefaults] setObject:event.UUID forKey:@"eventid"];
        // unable to save event to the calendar
        return NO;
    }
}

    
+ (BOOL)removeEventAt:(NSDate*)eventDate withEndDate:(NSDate*)endDate withTitle:(NSString*)title inLocation:(NSString*)location
{
    EKEventStore *eventStore = [[EKEventStore alloc] init];
    NSLog(@"Event ID: %@",[[NSUserDefaults standardUserDefaults] objectForKey:title]);

    BOOL result;
    NSError* err = nil;
    
    EKEvent *existingEvent = [eventStore eventWithIdentifier:[[NSUserDefaults standardUserDefaults] objectForKey:title]];
        if (existingEvent != nil) {
            
            EKReminder *reminder = [EKReminder reminderWithEventStore:eventStore];
            
            [eventStore removeReminder:reminder commit:YES error:&err];
        
            result = [eventStore removeEvent:existingEvent span:EKSpanThisEvent commit:YES error:&err];
           
        }
    if (result) {
         [[NSUserDefaults standardUserDefaults] removeObjectForKey:title];
        return YES;
    } else {
         NSLog(@"Error unsave event: %@", err);
        // unable to save event to the calendar
        return NO;
    }
    
}

@end





2)  Write This Following Code :


* ViewController ( Add & Remove Event ) 

ViewController.m :


#import "ViewController.h"
#import "MyCalendar.h"

@interface ViewController ()
{
           //------------ string for time zone

           NSString *tzName;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self fetchEvents];
    
    // Call Method For Remove
    
   // [self removeEvent];

}

#pragma mark Event Save to Local calender


- (void)fetchEvents
{
    NSDate *startDate = [self setDateManually:@"2016-04-06" time:@"6:36 pm"] ;
    
    NSDate *endDate = [self setDateManually:@"2016-04-10" time:@"9:41 pm"] ;
    
    NSString *calLocation = [NSString stringWithFormat:@"Ahmedabad\nCTM"];
    
    
    [MyCalendar requestAccess:^(BOOL granted, NSError *error) {
        if (granted) {
            BOOL result = [MyCalendar addEventAt:startDate withEndDate:endDate withTitle:@"Birth Day Party"  inLocation:calLocation latitude:@"23.0300" longitude:@"72.5800"];
            if (result) {
                // added to calendar
            } else {
                // unable to create event/calendar
            }
        } else {
            // you don't have permissions to access calendars
        }
    }];
    
    
}

-(NSDate *)setDateManually:(NSString *)dateStr time:(NSString *)time
{
    NSString *temp = [NSString stringWithFormat:@"%@" , dateStr] ;
    
    NSRange stringRange = {0, MIN([temp length], 10)};
    stringRange = [temp rangeOfComposedCharacterSequencesForRange:stringRange];
    
    NSString *shortString = [temp substringWithRange:stringRange];
    
    NSDateFormatter* gmtDf = [[NSDateFormatter alloc] init] ;
    

    NSString *timeZone=[self getTimezone];

    [gmtDf setTimeZone:[NSTimeZone timeZoneWithName: timeZone]];
    [gmtDf setDateFormat:@"yyyy-MM-dd"];
    
    NSDate* gmtDate = [gmtDf dateFromString:shortString];
    
    
    
    NSRange stringRange1 = {0, MIN([time length], 5)};
    stringRange1 = [time rangeOfComposedCharacterSequencesForRange:stringRange1];
    
    NSString *shortString1 = [time substringWithRange:stringRange1];
    
    
    NSString *hourStr = [shortString1 componentsSeparatedByString:@":"][0];
    NSString *minutesStr = [shortString1 componentsSeparatedByString:@":"][1];
    
    NSString *timeSpecific = [time substringFromIndex:[time length] - 2];  //// AM , PM
    
    NSInteger hour ;
    NSInteger minutes ;
    
    
    if([timeSpecific isEqualToString:@"am"])
    {
        hour  = [hourStr intValue];
        minutes  = [minutesStr intValue];
    }
    else
    {
        hour = 12 + [hourStr intValue];
        minutes = [minutesStr intValue];
    }
    
    NSCalendar* usCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] ;
    [usCalendar setTimeZone:[NSTimeZone timeZoneWithName:timeZone]];
    
    NSDate *d = [usCalendar dateBySettingHour:hour minute:minutes second:0 ofDate:gmtDate options:0];
    
    NSLog(@"date here : %@" , d) ;
    
    return d ;
}

-(NSString *)getTimezone
{
    NSDate *today = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    // display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
    [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
    NSString *currentTime = [dateFormatter stringFromDate:today];
    
    NSLog(@"User's current time in their preference format:%@",currentTime);
    NSTimeZone *timeZone = [NSTimeZone localTimeZone];
    tzName = [timeZone name];
    return tzName;

}

-(void)removeEvent
{
    NSDate *startDate = [self setDateManually:@"2016-04-06" time:@"6:36 pm"] ;
    
    NSDate *endDate = [self setDateManually:@"2016-04-10" time:@"9:41 pm"] ;
    
    [MyCalendar requestAccess:^(BOOL granted, NSError *error) {
        if (granted) {
            BOOL result = [MyCalendar removeEventAt:startDate withEndDate:endDate withTitle:@"Birth Day Party"  inLocation:@"Ahmedabad"];
            
          
            if (result) {
                // added to calendar
            } else {
                // unable to create event/calendar
            }
        } else {
            // you don't have permissions to access calendars
        }
    }];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end