Friday 18 March 2016

Custom layout for Collection View

UICollectionView provides a way in which we can arrange our data in a grid . Some times we may encounter a problem where we want to design the grid in our way , for example we may want to show the layout of the collection view cell based on the content size of the data we want to display in the collection view. In this way we have to define our custom layout for the each cell based on the content size of the data.


Collection view layouts are subclasses of  the abstract UICollectionViewLayout class. They define the visual attribute of each item in your collection view.

The individual attributes are instances of  UICollectionViewLayoutAttributes and contain the properties of each item in your collection view, such as the frame or opacity of the item .

To customize the layout of the the collection view we have to understand how collection view and layout object works together. Collection view layout process is a collaboration between collection view and the layout object.
When collection view needs some information about layout, it asks your layout object to provide it by calling certain methods in a specific order:

1) prepareLayout
2) collectionViewContentSize
3) layoutAttributesForElementsInRect:

Your layout subclass must implement above mentioned methods:

1) prepareLayout(): It is called when a layout operation is to take place. Here we make calculations to define the collection view size and and the position of the items.

2) collectionViewContentSize(): In this method we return the  height and width of the entire collection view.

3) layoutAttributesForElementInRect(_:) In this method we return  the layout attributes for all the items in a given rect as  UICollectionViewLayoutAttributes .

Friday 11 March 2016

Working with UIAlertController

UIAlertView and UIActionSheet are deprecated in iOS8. Now to show alert , we use UIAlertViewController which gives a more functionality to show alert. With this single class, we can create alert and add multiple actions to it. Each action has a completion handler called when user tap on that action button .

A UIAlertController objects displays an alert message to the user. This class replaces the UIAlertView and UIActionSheet  classes for displaying alerts. Although UIAlertController is a subclass of the UIViewController but it does not support subclassing  further .

UIAlertController is initialized with a title, message, and whether it prefers to be displayed as an alert or action sheet. Alert views are presented modally in the center of their presenting view controllers, where as action sheets are anchored to the bottom. Alerts can have both buttons and text fields, while action sheet only support buttons.


Creating an Alert Controller :

UIAlertController *alert = [UIAlertController  alertControllerWithTitle:@"My Alert"
                                                 message:@"This is an alert."
                                                 preferredStyle:UIAlertControllerStyleAlert];




title
The title of the alert. Use this string to get the user’s attention and communicate the reason for the alert.
message
Descriptive text that provides additional details about the reason for the alert.
preferredStyle
The style to use when presenting the alert controller. Use this parameter to configure the alert controller as an action sheet or as a modal alert.

When configuring an alert with the UIAlertControllerStyleAlert style , we can also  add text fields to the alert interface. The alert controller provide a block for configuring  text fields prior to display. The alert controller maintains a reference to each text field so that we can access its value later.

We can associate actions with  alert controller to give the user a way to respond. Actions are displayed as buttons in the alert . The action object provides the button text and the action to be performed when that button is tapped.

Creating an Action:

UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"
                                               style: UIAlertActionStyleDefault
                                            handler: ^(UIAlertAction * action) {
                                           
                                          }];

[alert addAction: okAction];
[self  presentViewController:alert animated: YES  completion: nil];


Add TextFields:

-(void)addTextFieldWithConfigurationHandler:(void  (^)
  (UITextField * textField) ) configurationHandler

Calling this method adds an editable text field to the alert. We can call this method more than once to  add additional text fields. The text fields are stacked in the resulting alert.We can add a text field only if the  preferredStyle  property is set to UIAlertControllerStyleAlert.


References:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAlertController_class/#//apple_ref/occ/instm/UIAlertController/addTextFieldWithConfigurationHandler:

   

Friday 4 March 2016

Get the height of the text in textview/textfield

Some times we may have need to set the height of the textfield or textview based on the text size contained in the textfield or textview. 

Before iOS 7, we used sizeWithFont: method  to get the desired height, but now it is deprecated. So to get/set the height of the textview/textfield based on the text to be stored in it, we use:

For example: We have textView to show some text . The text length may be different. What if we have some other view there just touching  the  lower left corner of the text field. Though textView can contain different text say one line or multiple lines of text.  Then the position of that other view depends on the height of the textView.

//get the rect size of the counting text

  //set the attribute of the text, like font size and family and some other option
 NSDictionary *attributes  =@{NSFontAttributeName:[UIFont fontWithName:@"Helvetica Neue" size:14]};



CGRect rect = [[text to be stored in view] boundingRectWithSize:CGSizeMake(txtFieldWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];

Now from rect, we can extract the height and make the changes in the frame of the textfield so that textfield has the proper height to contain the text.
So we have approach like this:

 First calculate the text height to be stored in textView using above mentioned method. Then change the frame of the textView to adjust the text in it. After that also make some changes in the frame of the other view so that it places just touching the lower left corer of the textView.