Wednesday, December 14, 2016

Adding images to UITextFields

I created an @IBDesignable to allow developers to add an image to UITextFields on the Storyboard. You just have to add this file to your project:
 
@IBDesignable
class DesignableUITextField: UITextField {
    
    // Provides left padding for images
    override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
        var textRect = super.leftViewRect(forBounds: bounds)
        textRect.origin.x += leftPadding
        return textRect
    }
    
    @IBInspectable var leftImage: UIImage? {
        didSet {
            updateView()
        }
    }
    
    @IBInspectable var leftPadding: CGFloat = 0
    
    @IBInspectable var color: UIColor = UIColor.lightGray {
        didSet {
            updateView()
        }
    }
    
    func updateView() {
        if let image = leftImage {
            leftViewMode = UITextFieldViewMode.always
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
            imageView.image = image
            // Note: In order for your image to use the tint color, you have to select 
            // the image in the Assets.xcassets and change the "Render As" property to 
            // "Template Image".
            imageView.tintColor = color
            leftView = imageView
        } else {
            leftViewMode = UITextFieldViewMode.never
            leftView = nil
        }
        
        // Placeholder text color
        attributedPlaceholder = NSAttributedString(string: 
                placeholder != nil ?  
                placeholder! : "", 
                attributes:[NSForegroundColorAttributeName: color])
    }
}
 

Then add a UITextField to your view and set the custom class name for it:

You now have 3 properties open for you to add an image, padding and color. Color affects the image and placeholder text so they match. Note: The color of the image won't take effect until you run your project.


At runtime the color of the image will change:

Sunday, December 11, 2016

Part 15 - UIView's Installed Property


  • If checked (true), the view will be installed on the user's device when downloaded from the App Store.
  • An example of use is having two different images you want for different devices. One for iPhone, one for iPad. Instead of installing a small and large image on the person's device, you can just install one image per device.
    Example:
    Only install small image on iPhones.

    Only install large image on iPads.



(Xcode 8, Swift 3)

Part 14 - UIView's Stretching Property

  • It was used to handle corners of images, to prevent them from stretching while stretching out the other parts that would not look weird.
  • This property is actually deprecated and should not be used. Instead, you should use Image Slicing.
    Example of Image Slicing:



Reference: http://macoscope.com/blog/stretchable-images-using-interface-builder/

(Xcode 8, Swift 3)

Part 13 - UIView's Autoresize Subviews Property

  • Default is checked (true). Allows you to use the Autosizing for the UIView on the Size Inspector.
    Example:
  • When unchecked (false), any Autoresizing settings on the Size Inspector has no effect.
    Example of this setting on and off:
  • In code you use autoresizesSubviews property to set it to true or false.


(Xcode 8, Swift 3)

Saturday, December 10, 2016

Part 12 - UIView's Clip To Bounds Property

  • When unchecked (false), subviews in a UIView can extend outside the border of the parent UIView.
    Example:
  • When checked (true), subviews will not be drawn beyond the border of the parent UIView. Subviews are clipped.
    Example:
  • When checked (true), you cannot have a shadow on the UIView since the shadow is drawn outside the UIView's border.
  • In code you refer to UIView.clipsToBounds.

Part 11 - UIView's Clear Graphics Context

  • "Graphics Context" is defined by Apple as: "A graphics context represents a drawing destination."
  • "Context" is like scope. In this case it is the bounds of the object.
  • If true, clears what is drawn and redraws the view. Prevents visual artifacts from persisting after redrawing.
  • Property is clearsContextBeforeDrawing in code.
  • If unchecked you are responsible for redrawing.

Part 10 - UIView's Hidden Property

  • Setting to true will hide the UIView and everything inside the UIView. (You can still see it on the storyboard though.)
  • Set to true instead of changing Alpha to zero when you want to hide something.
  • If you want to animate hiding/showing, use Alpha. Hidden is not animatable.
  • All touch events are ignored when the UIView's hidden property is true.

Part 9 - UIView's Opaque Property

  • Whether the Opaque property is true or false it will not hide/show the UIView.
  • This property is simply a hint to the drawing system to improve performance when set to true. If it knows the UIView is opaque then it won't draw anything behind it.
  • If Alpha is less than one, this property should be set to false.
  • From Apple documentation: The opaque property has no effect in system-provided classes such as UIButton, UILabel, UITableViewCell, and so on.

Part 8 - UIView's Tint Property



  • Visually indicates which controls are active or have actions associated with them.
  • Use tintColor in code to set Tint.
    Example:
     
    view.tintColor = UIColor.red
     
    
  • Setting Tint on a UIView changes the tint for all subviews.
    Example:
  • You can override Tint set by the parent UIView by setting Tint on the control.
  • Globally set Tint in the AppDelegate.
    Example:
     
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        window?.tintColor = UIColor.purple
        
        return true
    }
     
    
  • Globally set Tint through Storyboard.
    Example:
  • The non-transparent parts of a UIImage can use the Tint color.
    Change the "Render As" property to "Template Image". Done from the image in the Assets.xcassets:
  • Note: As of Xcode 8, the tint will only show on the image during run-time, not design-time on the StoryBoard.


(Xcode 8)

Part 7 - UIView's Background Color Property


  • Gives the UIView a color
  • You can animate the color change
  • Property in code is called backgroundColor
  • You can set the Background color to an image:
     
    view.backgroundColor = UIColor(patternImage: UIImage(named: "myImage")!)
     
    

Part 6 - UIView's Alpha Property

  • Changes the transparency (ability to see through) a UIView.
  • 0 = Completely invisible
  • 1 = Completely solid (opaque)
  • Alpha affects the transparency of all subviews
  • You can animate this property
  • On a label, the alpha property affects the text
  • On a button, the alpha property also affects the text
  • If you want to preserve Alpha on text (make opaque) and make the rest partially transparent then set the Opacity of the Background Color
  • Changing the Alpha property of a view does not affect its parent view's Alpha
  • If Alpha is less than 1 then you should uncheck the Opaque property (set to false)
  • If Alpha is set to zero, the control no longer accepts inputs or touches. For example, a UIButton that has it's Alpha set to zero can no longer be clicked.

Friday, December 9, 2016

Part 5 - UIView's Multiple Touch Property

  • By default a UIView can only receive one touch.
  • Enabling Multiple Touch allows the UIView to receive more than one touch.
  • In code you reference the multipleTouchEnabled property

Example

In this example the tan area has Multiple Touch on while the white area does not.


Code

 
class ViewController: UIViewController {

    @IBOutlet weak var touchesLabel: UILabel!
    @IBOutlet weak var touchPointsLabel: UILabel!
    
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        // Number of Touches
        touchesLabel.text = "\(touches.count)"
        
        // Coordinates of the Touches
        var coordinates = ""
        var touchNumber = 0
        
        for touch in touches {
            touchNumber = touchNumber + 1
            let point = touch.location(in: view)
            coordinates = coordinates + "Touch \(touchNumber): [\(point.x), \(point.y)] \n"
        }
        
        touchPointsLabel.text = coordinates
    }
}
 



(Xcode 8, Swift 3.0)

Part 4 - UIView's User Interaction Enabled Property

When the user touches the screen, this is called a "user interaction". For a UIView, this property is defaulted to true. In code this property is userInteractionEnabled.

Observations

  • Unchecking this property for a button prevents that button from being touched.
  • If a UIView has User Interaction Enabled set to false, touches will still pass through to the views below it.
    Example:
         A - A UIView with User Interaction Enabled set to false.
         B - A UIButton.
         The button can still be clicked.
  • Animations set User Interaction Enabled to false during the animation.
  • Setting User Interaction Enabled to false on a parent UIView will disable user interaction on all UIViews within the parent (all subviews).
    Example:
         The button will not work.


(Xcode 8, Swift 3.0)

Thursday, December 8, 2016

Part 3 - UIView's Tag Property

The Tag property is a number and when used with the corresponding viewWithTag function one can access a specific subview without the need for an outlet.

Example

 
override func viewDidLoad() {
    super.viewDidLoad()
    
    let label = view.viewWithTag(1) as! UILabel
    label.text = "New text here"
}
 

Observations

  • You can give the same Tag to multiple views
  • The first view in the document outline matching the Tag number is selected when viewWithTag is used


(Swift 3.0)

Part 2 - UIView's Semantic Property

Semantic is the second property on the UIView's Attribute Inspector. Also called semanticContentAttribute in code.

Semantic means "relating to meaning in language or logic".

This seems like a poorly chosen word since, as you will see, this has more to do with languages rather than meanings in languages.

Semantic

When your app is used on a device that is set to a language that reads from right to left (like Arabic), iOS will automatically flip controls to the other side of the screen to help make it more natural looking for those users.

Using the Semantic property you can override this default behavior.

How to Flip

  • Provide a leading and trailing constraint
  • Leave label/textview's text alignment on "Natural":

Flipping Images

Thanks to wakachamo (comments below) I learned that you can flip images through the assets catalog.

Prevent Flipping

  • Manually setting a label/textview's text alignment
  • If you have constraints on controls, you may have to change the parent's Semantic property from "Unspecified"
  • Changing the Semantic property to anything but "Unspecified"

Other Observations/Notes


Wednesday, December 7, 2016

Part 1 - UIView's Content Mode

I decided to go down and learn every property for the UIView on the Attributes Inspector. Part of the whole "leave nothing misunderstood" quest.

Content Mode

I think most of us know how this applies to the UIImageView control but what about just the UIView?

This took a lot of digging to understand this property.

Here are some things I've found out but none of which actually came from Apple:
  • For an image view, this is talking about the position/scaling of image.
  • For a UIView that draws its content, this is talking about the drawn content.
  • It does not affect the layout of subviews inside a UIView.

How is this property beneficial?

  • I won't go into how it is beneficial for a UIImageView. Most of you probably already know and if you don't then check out this great article.
  • Use this property when drawing a path and then handling how that path is then positioned/scaled when the UIView's bounds or frame changes.
  • The idea is to save processing time on redrawing when UIView's bounds change.


More Info from Apple

Tuesday, December 6, 2016

Make Your Apps Look Awesome (and other tips)

A lot of cool things taught in this video series. I make sure you know everything I am teaching and not just glaze things over.

Part 1

  • Different image options
  • Where to find great looking custom fonts
  • How to find multiple fonts that look great together
  • How to download and add custom fonts to your iOS project
  • How to set options so your text always fits inside your label no matter what the size

Part 2

  • How to add a drop shadow to text in labels
  • How to use the Assistant Editor to preview your changes on different devices at once
  • Adjusting the baseline to correct vertical alignment of text
  • A handy way to use the Multiplier property on constraints for correct scaling of objects in your UI

Part 3

  • How to customize a control using IBDesignable
  • A little bit about inheritance
  • How to add borders to controls
  • How to change the color of borders
  • How to make rounded corners with the cornerRadius property

Part 4

  • Create a modal popup
  • Use a StackView
  • Use a blur control for the background
  • Dismiss the popup when touching outside of it

Part 5

  • Hide passwords while typing
  • Change Stackview spacing
  • Change the "Return" text on the keyboard to "Done"
  • Implement the UITextFieldDelegate
  • Understand what a Responder is
  • Dismissing the keyboard

Part 6

  • How to create a custom UIButton that animates when you click it
  • What the transform property is
  • What CGAffineTransform is and how to use it to scale an object
  • How to use spring with damping animation
  • What "curve" means when animating


SwiftUI Search & Filter with Combine - Part 3 (iOS, Xcode 13, SwiftUI, 2...

In part 3 of the Searchable video series, I show you how to use Combine in #SwiftUI for the search and filter logic connected to the searcha...