Day 120 – Make my first iPhone app in 30 weeks (Motion and Dynamics)

This is part of “Make my first iPhone app in 30 weeks” series.

Motion (adds subtle motion)

  • UIInterpolatingMotionEffect – allows to add depth to the UI
  • UIMotionEffectGroup – Add UIInterpolatingMotionEffect objects to apply change simultaneously

Dynamics (adds realism)

  • UIDynamicAnimator controls the physics engine
  • UIDynamicBehavior needs the objects that conform to UIDynamicItem protocol to be added to it. UIView and UICollectionViewCell conform to this protocol out of the box.
    • UIGravityBehavior
    • UICollisionBehavior
    • UIAttachmentBehavior
    • UISnapBehavior
    • UIPushBehavior
    • UIDynamicItemBehavior
  • UIDynamicAnimatorDelegate allows the delegate object to be notified when the animation pauses or resumes.

Day 119 – Make my first iPhone app in 16 weeks (Concurrency)

This is part of “Make my first iPhone app in 16 weeks” series.

Concurrency

When to avoid:

  1. Networking (use asynchronous API’s instead)
    1. initWithContentsofURL needs to be used with asynchronous API’s. Otherwise, it will block the main thread.
  2. Reachability (use asynchronous API’s instead)
  3. Idle Behavior (use NSTimer instead)

Best concurrency architecture

  1. Thread confinement – one object on one thread (NSOperation provides this functionality)

NSOperation

  1. Encapsulates code & data
  2. Can query for the state of execution (isExecuting, isFinished, and isCancelled)
  3. Can set dependencies (let a particular operation be dependent upon another operation) – very useful!
  4. Can set priority

NSOperationQueue

Regulates a set of NSOperation objects

  1. Can suspend and resume
  2. Can up-throttle or down-throttle the queue

Day 118 – Make my first iPhone app in 16 weeks (imageNamed vs. imageWithContentsOfFile)

This is part of “Make my first iPhone app in 16 weeks” series.

imageNamed vs. imageWithContentsOfFile

  • imageNamed decompresses the image immediately
  • imageNamed cached by OS (perfect for frequently used images)
  • imageNamed is used by iOS to load nib referenced images (images referenced in nib or storyboard)
  • imageWithContentsOfFile decompresses the image on demand (lazily loaded when it displays on the screen)
  • imageWithContentsOfFile is NOT cached by OS (perfect for infrequently used images so that there is no cache pressure)

 

Day 104 to 117 – Make my first iPhone app in 16 weeks (UICollectionView)

This is part of “Make my first iPhone app in 16 weeks” series.

  • Controller – UICollectionViewController (native view controller for UICollectionView)
  • View – UICollectionView
    • UICollectionView
    • UICollectionViewCell
    • UICollectionReusableView (Header/Footer/DecorationViews)
  • Content – UICollectionViewDataSource & UICollectionViewDelegate
  • Layout – objects that provide presentation logics for view objects
    • UICollectionViewLayout – This is a blank slate layout object. You have to register view objects, add UICollectionViewLayoutAttributes objects that describe the presentation logic of each view object
    • UICollectionViewLayoutAttributes – This provides the presentation logic for each view object.
    • UICollectionViewUpdateItem – The layout object receives instances of the UICollectionViewUpdateItem class whenever data items are inserted, deleted, or moved within the collection view. You never need to create instances of this class yourself.
  • Flow Layout (concrete subclass of Layout object)
    • Flow Layout – comes with two optional supplementary reusable views (header/footer)
    • UICollectionViewDelegateFlowLayout – Methods to work the flow layout

Configuration of views

  1. Registration views (If you registered the views in Storyboard, DO NOT register them programmatically)
    1. Register programmatically
    2. Storyboard
  2. Deque

Layout of views

  1. If you configured a cell without giving it a size, it will disappear. I configured a header view in Storyboard but didn’t give it a size through headerReferenceSize or collectionView:layout:referenceSizeForHeaderInSection: method, so dequeing the supplementary view kept throwing an error.

Day 97 to 103 – Make my first iPhone app in 16 weeks (variable storage types)

This is part of “Make my first iPhone app in 16 weeks” series.

Variable storage types

  1. __block – any variable that’s marked with this storage type will retain its value that was modified within a block beyond the enclosing scope of the block.
  2. __weak – weak pointer
  3. __strong – strong pointer
  4. const – variable that cannot be reassigned or modified
  5. extern – way to declare a global variable
  6. static – variable reachable only within its own implementation (.m file of the .h file where the static variable is declared in)

Day 96 – Make my first iPhone app in 16 weeks (Delegate)

This is part of “Make my first iPhone app in 16 weeks” series.

So I want to have my UIView to draw circles around four corners of the paper in the image. My view controller knows where the circles need to be drawn but my view does not have a clue! So iOS MVC explicitly prohibits View making a contact with Controller. What do I do?

The answer is “Delegate” I set the controller to be the delegate of the view.

In my view.h

@protocol CornerDetectionViewDelegate 
- (void)someMethod;
@end

@interface CornerDetectionView : UIView {
    id delegate;
}
@property (nonatomic, strong) id delegate;
@end

Then in view.m

@synthesize delegate;

Then in my controller.m

@interface EditImageViewController () 
@property (strong, nonatomic) IBOutlet CornerDetectionView *cornerDetectionView;
@end

@implementation EditImageViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Sets the controller as a delegate for CornerDetectionView
    self.cornerDetectionView.delegate = self;
}
- (void)someMethod
{
    // Implement this method
}
@end

Day 94 to 95 – Make my first iPhone app in 16 weeks (UIView)

This is part of “Make my first iPhone app in 16 weeks” series

There are two ways to draw something on screen:

  1. OpenGL (C API)
  2. Quartz (drawing kit), UIKit (display kit), or Core Animation (translation, transformation, rotation animations)

Regardless of which method you use, the drawing must happen within UIView or its subclasses.

The View Drawing Cycle

  1. drawRect: method is called on the view to display the contents. As the name of method implies, iOS passes a rectangle with the visible contents to the view. Override this method for custom views but NEVER call this method yourself.
    1. drawRect is called when the view appears initially
    2. Also it’s called automatically when the following events happen
      1. Moving or removing another view that was partially obscuring your view
      2. Making a previously hidden view visible again by setting its hidden property to NO
      3. Scrolling a view off of the screen and then back onto the screen
      4. Explicitly calling the setNeedsDisplay or setNeedsDisplayInRect: method of your view
  2. The view marks itself as updated and waits for new actions to arrive and trigger another update cycle
  3. If you want to manually change/update the contents of the view, call the setNeedsDisplay or setNeedsDisplayInRect:

Coordinate Systems

  1. User coordinate system – used when a user issues drawing commands
  2. View coordinate system – fixed coordinates relative to the view
  3. Hardware coordinate system – fixed coordinates on the physical device

Points vs Pixels

The purpose for using points system is to render relatively the same size output independent of the device. For example, one pixel line in retina display may correspond to one point which may map to 2 physical pixels (depends on the contentScaleFactor of the view). If you need a custom scale factor, adjust it in drawRect.

Each view has drawing context (CGContextRef) that describes stroke, color, fill and etc. To get the current drawing context, call UIGraphicsGetCurrentContext function.

Animating UIView

There are some built-in animations you can do with UIView without interacting directly with Core Graphics framework. Read documentation here.

Where as UIImage takes into account scale factor and appropriately displays the contents automatically, Quartz images do not account for scale factor. User should check the scale factor and adjust the image size accordingly.

Draw in Offscreen Bitmap

  1. Create a CGRect
  2. Set drawing context with UIGraphicsBeginImageContextWithOptions function
  3. Draw the image in that rect

Day 97 – Make my first iPhone app in 16 weeks (Strong vs Weak)

This is part of “Make my first iPhone app in 16 weeks” series.

I haven’t been blogging about the progress of my work for a couple weeks. It’s due part to my Christmas + New Years + My B-day + Wedding Anniversary + My hubby’s B-day break (Dec is a killer month for me personally) and the other part to getting too absorbed in the making of the app and forgetting to blog about it :) Ok. Enough with my excuses.

I actually have made quite a progress. The app now takes a photo, calculates the right matrix to un-skew the art work to its rectangular shape in the approximately correct proportion. I’m currently in the process of refactoring my code to make it more manageable.

Today, as I was thinking about the memory management issue (I keep getting memory warning from the device), I realized I didn’t fully understand the difference between different property attributes under ARC system.

  1. Strong – Any object that points “Strongly” to another object will increment the reference pointer by 1
  2. Retain (Same as Strong under ARC system. Use Strong for ARC to work)
  3. Weak – Any object that points “Weakly” to another object will simply point to it but will NOT increment the reference counter by 1
  4. Unsafe_unretained – Use with primitive data (BOOL, float, int …etc)
  5. Assign (Same as unsafe_unretained under ARC system. Use Unsafe_unretained for ARC to work)
  6. Copy – Retains a “Copy” of the object which does not reflect the changes applied by other external objects that have pointers to it.

I will probably make the most use out of strong and weak but I’m still not 100% sure about WHEN and WHERE and HOW to use either one. Then I found this amazing tutorial.

One of the limitations of ARC is that it only works with Obj-C objects. If you use Core Foundation objects, you are responsible for releasing those objects yourself. If you use Core Foundations objects interchangeably with objective-C objects, the following are a simple set of rules that will help convert from one to the other.

  1. __bridge (cast without transfer of ownership. Use when you want to use a type temporarily as if it is the other)
  2. __bridge_transfer (cast and gives ownership to ARC) – Use whenever CF…create/copy/retain… functions is used
    1. (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes ( ... )
    2. Alternative – wrap the code in CFBridgingRelease()
  3. __bridge_retained (cast and relieves ownership from ARC)
    1. CFStringRef s2 = (__bridge_retained CFStringRef)s1;
    2. Alternative – wrap the code in CFBridgingRetain()