Tag: swift

  • My first experience of attending the international iOS conference, try! Swift Tokyo 2019

    My first experience of attending the international iOS conference, try! Swift Tokyo 2019

    I attended the try! Swift Tokyo 2019, which is my first attending iOS conference. I was very excited. I’ll share my experience with that.

    Before I decide to attend the conference, I asked myself why I should go there? Because All of the conference videos will be upload on Youtube.

    I thought If I go there, I can meet iOS engineers from the world by talking about iOS topics, and also I can ask about the presentation. Also, I can travel the Tokyo and visit the Shinjuku LINE office. That thing makes me attend the conference.

     

    First Day

    Conference Hall

    Conference Hall

    They prepared the T-Shirt and Bag for attendees.

    They prepared the T-Shirt and Bag for attendees.

    try! Swift held on for three days.

    try! Swift held on for three days.

    BB7C9780-DD94-4EEB-AFE8-2D57FDEEED58_1_105_c.jpeg

    Hello Firebase!

    Hello Firebase!

    Wow, 900 attendees!

    Wow, 900 attendees!

    Sponsors.

    Sponsors.

    He talked about server-side swift.

    He talked about server-side swift.

    He talked about Cocoa Binding.

    He talked about Cocoa Binding.

    During the schedule, each session was usually presented for 20 minutes, and the lighting session was performed for 10 minutes.

     

    Break Time

    I was ashamed to say, Hi. But I tried networking while taking a break time. 😅

    Barista gives us such great coffee every break time! It's free. ☕️

    Barista gives us such great coffee every break time! It’s free. ☕️

    5c0e6 e1787 image asset

    I’ve been working at LINE 😁

    I’ve been working at LINE 😁

    1466503B-AB16-4F86-86B0-0C330D7FE1D3_1_105_c.jpeg

    443EBBD6-2CB1-44CE-9370-1DEC82C90CCF_1_105_c.jpeg

    Dinner

    After the conference, I met iOS engineers from Korea. My coworker invited me to join the dinner. There are so many tasty foods.

    Cherry Blossom was so beautiful.

    Cherry Blossom was so beautiful.

    905E0C60-52F4-4A0B-8B96-0D190465B226_1_105_c.jpeg

    1F764039-BCC9-434B-8BD3-485AC72CC78F_1_105_c.jpeg

    I met such great engineers who are working in Seoul.

    I met such great engineers who are working in Seoul.

     

    Second Day

    In the morning, I visited the Maruyama Coffee to eat breakfast. I highly recommend this cafe.

    Maruyama Coffee

    Maruyama Coffee

    1D0BA535-F2E6-4B46-92DA-BFB72589FA78_1_105_c.jpeg

    9097E8C6-6C5C-4871-B983-2B60128488AB_1_105_c.jpeg

    The second day started at 9:00.

    IBM Kitura

    IBM Kitura

    He made a presentation about Kitura.

    He made a presentation about Kitura.

     

    Lunch Time

    I had lunch for an hour and a half. I chose the lunch box. After I ate lunch, I went to a cafe near the conference hall. It took about 5 minutes to walk.

    7EEC4A93-DB56-4A42-A578-5C1A27A62918_1_105_c.jpeg

    12A038A8-EBD8-42BE-A142-F7D513D458B2_1_105_c.jpeg

    2A83D3B0-2431-4BED-AB94-39431631109F_1_105_c.jpeg

    While having a break time with coffee, I checked the conference slack channel. Someone wrote in a Slack channel that they are looking for people to go to see cherry blossoms. Slack was good at networking with attendees. 😀

     

    Party

    I had a great time at the party. There were almost 900 iOS engineers!

    I talked with peoples while waiting in a row to pick some foods.

    I talked with peoples while waiting in a row to pick some foods.

    2E159BBD-360D-449D-8FA6-864F33BDBEE4_1_105_c.jpeg

    0ADE1F3F-8C75-4FF2-91D5-9CD6E8106ABA_1_105_c.jpeg

    Salmon was tasty.

    Salmon was tasty.

    9f910 c9a8b image asset

     

    Third day

    I attended ‘Build a Cloud-Native Swift Backend.’ It’s an IBM Kitura workshop.

    76174C17-B81D-4544-81C7-C75254C50AE4_1_105_c.jpeg

    A799E872-C7D7-4A49-9134-14532AFC6A04_1_105_c.jpeg

    It was great. I learned Docker, Kitura, and PostgreSQL.

    It was great. I learned Docker, Kitura, and PostgreSQL.

    Hello Kitura!

    Hello Kitura!

    Peer Lab

    Sponsors rent their offices for Peer Lab. Peer Lab was networking time.

    Attendees brought MacBook and introduced who I am. I also introduced my self. It was a great time. We swapped business cards with each other and made friends with LinkedIn.

    2ED51357-F144-46E6-9070-FB0B99B87159_1_105_c.jpeg

    LINE Shinjuku office

    LINE Shinjuku office

    0e9a1 78663 image asset

    6F3DE976-582C-4735-864F-6A17A578F2FF_1_105_c.jpeg

    91A61DCE-88E3-45E9-B01F-48F1E8A92D22_1_105_c.jpeg

    20520E59-F848-4B62-AA77-C91D5606B0F5_1_105_c.jpeg

    Giant Brown 😱

    Giant Brown 😱

     

    Conclusion

    Everything was great! I learned new things and made new friends. Conference gave me the motivation to present my knowledge and to speak English by attending Peer Lab, Party, and Workshop.

  • How to Animate Path Using CoreAnimation in iOS – SVG to UIBezierPath

    How to Animate Path Using CoreAnimation in iOS – SVG to UIBezierPath

    I wrote a Behind the scene of delightful animation it is about Animation patterns in modern iOS Apps. In this post, I’ll introduce how to animate path using CoreAnimation.

    Before we start coding, we need to prepare the vector image like an SVG and then convert it to UIBeizierpath.

     

    SVG Image

    SVG acronym is Scalable Vector Graphics developed by W3C. Unfortunately, iOS does not support the SVG format. So We need to convert it to UIBeizierpath.

    #block-yui_3_17_2_1_1589705258661_10561 .sqs-gallery-block-grid .sqs-gallery-design-grid { margin-right: -0px; }
    #block-yui_3_17_2_1_1589705258661_10561 .sqs-gallery-block-grid .sqs-gallery-design-grid-slide .margin-wrapper { margin-right: 0px; margin-bottom: 0px; }

    Look at path tag. Each character has the meaning of a drawing command. Uppercase uses absolute position, and lowercase uses relative position.

    • M = moveto

    • L = lineto

    • H = horizontal lineto

    • V = vertical lineto

    • C = curveto

    • S = smooth curveto

    • Q = quadratic Bézier curve

    • T = smooth quadratic Bézier curveto

    • A = elliptical Arc

    • Z = closepath

    We can convert it to UIBeizierPath.

    • move(to: CGPoint)

    • addCurve(to: CGPoint, controlPoint1: CGPoint, controlPoint2: CGPoint)

    • addQuadCurve(to: CGPoint, controlPoint: CGPoint)

    • addLine(to: CGPoint)

    • addArc(withCenter: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockWise: Bool)

     

    How to convert SVG to UIBeizierPath?

    Here is an example of Swift Logo.

    carbonDrawing.JPG

    Let’s convert it to UIBeizierPath step by step.

    <path d="m29.885 33.047c-4.667 2.696-11.084 2.973-17.54 0.206-5.2273-2.224-9.5646-6.117-12.345-10.565 1.3346 1.112 2.8916 2.002 4.5598 2.78 6.6672 3.125 13.333 2.911 18.024 0.008-0.003-0.003-0.005-0.005-0.007-0.008-6.673-5.116-12.345-11.789-16.571-17.238-0.8901-0.8898-1.5574-2.002-2.2247-3.0029 5.1159 4.671 13.235 10.565 16.126 12.234-6.116-6.451-11.566-14.458-11.344-14.236 9.676 9.787 18.685 15.348 18.685 15.348 0.298 0.168 0.528 0.308 0.713 0.433 0.195-0.496 0.366-1.011 0.51-1.545 1.557-5.672-0.222-12.123-4.115-17.461 9.008 5.4495 14.347 15.681 12.122 24.245-0.058 0.231-0.121 0.459-0.189 0.683 0.026 0.031 0.052 0.063 0.078 0.096 4.448 5.561 3.225 11.455 2.669 10.343-2.413-4.722-6.88-3.278-9.151-2.32z"/> 

    StartPoint is 29.88, 33.05

    StartPoint is 29.88, 33.05

    //First drawing command
    //m29.885 33.047
    move(to: CGPoint(x: 29.885, y: 33.05)

    The m command is easy. Just move the point using move(to: CGPoint).

    Second point is 12.34, 33.25. It is calculated by startPoint x: 29.885 - 17.54 = 12.35 and startPoint: y: 33.05 + 0.206 = 33.25.

    Second point is 12.34, 33.25. It is calculated by startPoint x: 29.885 – 17.54 = 12.35 and startPoint: y: 33.05 + 0.206 = 33.25.

    //Second drawing command
    //c-4.667 2.696-11.084 2.973-17.54 0.206
    addCurve(
    to: CGPoint(x: 12.35, y: 33.25), 
    controlPoint1: CGPoint(x: 25.22, y: 35.74), 
    controlPoint2: CGPoint(x: 18.8, y: 36.02)
    )

    Look at the c character. The c is meaning that curveTo is a relative position. It takes 3 points, which are controlPoint1, controlPoint2, and currentPoint. I was very confused that how can it be converted from (-4.667, 2.696), (-11.084, 2.973), and (-17.54, 0.206) to (12.35, 33.25), (25.22, 35.74), and (18.8, 36.02).

    Let’s look again. We take 3 points, which are controlPoint1, controlPoint2, and current Position.

    Let’s look again. We take 3 points, which are controlPoint1, controlPoint2, and current Position.

    controlPoint2.JPG

    controlPoint1.JPG

    The startPosition is CGPoint(x: 29.885, y: 33.05). And It was added curveTo relative to startPosition.

    • CurrentPosition(x: 12.35, y: 33.25) is calculated by 29.885 – 17.54 = 12.35 and 33.05 + 0.206 = 33.25

    • ControlPoint1(x: 25.22, y: 35.74) is calculated by 29.885 – 4.667 = 25.22 and 33.05 + 2.697 = 35.74

    • ControlPoint2(x: 18.8, y: 36.02) is calculated by 29.885 – 11.084 = 18.8 and 33.05 + 2.973 = 36.02

    And next position is also same. Just take a 3 position and calculate it relative to currentPosition(x: 12.35, y: 33.25) which is updated after add curveTo position. Here is the full path of Swift Logo.

    extension UIBezierPath {
    static var swift: UIBezierPath = {
        let bezierPath = UIBezierPath()
        bezierPath.move(to: CGPoint(x: 29.88, y: 33.05))
        bezierPath.addCurve(to: CGPoint(x: 12.35, y: 33.25), controlPoint1: CGPoint(x: 25.22, y: 35.74), controlPoint2: CGPoint(x: 18.8, y: 36.02))
        bezierPath.addCurve(to: CGPoint(x: 0, y: 22.69), controlPoint1: CGPoint(x: 7.12, y: 31.03), controlPoint2: CGPoint(x: 2.78, y: 27.14))
        bezierPath.addCurve(to: CGPoint(x: 4.56, y: 25.47), controlPoint1: CGPoint(x: 1.33, y: 23.8), controlPoint2: CGPoint(x: 2.89, y: 24.69))
        bezierPath.addCurve(to: CGPoint(x: 22.58, y: 25.48), controlPoint1: CGPoint(x: 11.23, y: 28.59), controlPoint2: CGPoint(x: 17.89, y: 28.38))
        bezierPath.addCurve(to: CGPoint(x: 22.58, y: 25.47), controlPoint1: CGPoint(x: 22.58, y: 25.47), controlPoint2: CGPoint(x: 22.58, y: 25.47))
        bezierPath.addCurve(to: CGPoint(x: 6.01, y: 8.23), controlPoint1: CGPoint(x: 15.9, y: 20.35), controlPoint2: CGPoint(x: 10.23, y: 13.68))
        bezierPath.addCurve(to: CGPoint(x: 3.78, y: 5.23), controlPoint1: CGPoint(x: 5.12, y: 7.34), controlPoint2: CGPoint(x: 4.45, y: 6.23))
        bezierPath.addCurve(to: CGPoint(x: 19.91, y: 17.46), controlPoint1: CGPoint(x: 8.9, y: 9.9), controlPoint2: CGPoint(x: 17.02, y: 15.79))
        bezierPath.addCurve(to: CGPoint(x: 8.56, y: 3.23), controlPoint1: CGPoint(x: 13.79, y: 11.01), controlPoint2: CGPoint(x: 8.34, y: 3))
        bezierPath.addCurve(to: CGPoint(x: 27.25, y: 18.57), controlPoint1: CGPoint(x: 18.24, y: 13.01), controlPoint2: CGPoint(x: 27.25, y: 18.57))
        bezierPath.addCurve(to: CGPoint(x: 27.96, y: 19.01), controlPoint1: CGPoint(x: 27.55, y: 18.74), controlPoint2: CGPoint(x: 27.78, y: 18.88))
        bezierPath.addCurve(to: CGPoint(x: 28.47, y: 17.46), controlPoint1: CGPoint(x: 28.16, y: 18.51), controlPoint2: CGPoint(x: 28.33, y: 18))
        bezierPath.addCurve(to: CGPoint(x: 24.36, y: 0), controlPoint1: CGPoint(x: 30.03, y: 11.79), controlPoint2: CGPoint(x: 28.25, y: 5.34))
        bezierPath.addCurve(to: CGPoint(x: 36.48, y: 24.25), controlPoint1: CGPoint(x: 33.36, y: 5.45), controlPoint2: CGPoint(x: 38.7, y: 15.68))
        bezierPath.addCurve(to: CGPoint(x: 36.29, y: 24.93), controlPoint1: CGPoint(x: 36.42, y: 24.48), controlPoint2: CGPoint(x: 36.36, y: 24.7))
        bezierPath.addCurve(to: CGPoint(x: 36.37, y: 25.02), controlPoint1: CGPoint(x: 36.32, y: 24.96), controlPoint2: CGPoint(x: 36.34, y: 24.99))
        bezierPath.addCurve(to: CGPoint(x: 39.04, y: 35.37), controlPoint1: CGPoint(x: 40.82, y: 30.59), controlPoint2: CGPoint(x: 39.59, y: 36.48))
        bezierPath.addCurve(to: CGPoint(x: 29.88, y: 33.05), controlPoint1: CGPoint(x: 36.62, y: 30.65), controlPoint2: CGPoint(x: 32.16, y: 32.09))
        bezierPath.close()
        return bezierPath
    }()
    }

     

    Let’s animating it.

    Path Animation

    PathAnimation

    PathAnimation

    class ViewController: UIViewController {
        var swiftPath: UIBezierPath = .swift
        lazy var logoLayer: CAShapeLayer = {
           let logoLayer = CAShapeLayer()
            logoLayer.path = swiftPath.cgPath
            logoLayer.strokeEnd = 0
            logoLayer.strokeStart = 0
            logoLayer.lineWidth = 2
    
            logoLayer.borderColor = UIColor.black.cgColor
            logoLayer.strokeColor = UIColor.black.cgColor
            logoLayer.fillColor = UIColor.white.cgColor
    
            logoLayer.position = CGPoint(x: 161, y: 247)
            return logoLayer
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            view.layer.addSublayer(logoLayer)
            startPathAnimation()
        }
    
        func startPathAnimation() {
            let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
            pathAnimation.fromValue = 0
            pathAnimation.toValue = 1
            pathAnimation.duration = 2
            pathAnimation.isRemovedOnCompletion = false
            pathAnimation.fillMode = .forwards
            logoLayer.add(pathAnimation, forKey: "line")
        }
    }

     

    Fill Color Animation

    fillColor.gif

    func startFillColorAnimation() {
      let fillColorAnimation: CABasicAnimation = CABasicAnimation(
      keyPath: "fillColor"
      )
      fillColorAnimation.duration = 1
      //Start Fill Color Animation after finishing path animation.
      fillColorAnimation.beginTime = CACurrentMediaTime() + 2
      fillColorAnimation.fromValue = UIColor.clear.cgColor
      fillColorAnimation.toValue = UIColor.red.cgColor
      fillColorAnimation.fillMode = .forwards
      //Keep color after complete animation
      fillColorAnimation.isRemovedOnCompletion = false
      logoLayer.add(fillColorAnimation, forKey: "fill")
     }

     

    Fill Gradient Color Animation

    Unlike SVG, CAShapeLayer doen’t support gradient color. So We should use CAGradientLayer to fill the gradient color in Swift logo. I’ll show you how to change the gradient color from original orange gradient color of Swift logo to blue gradient color of SwiftUI logo.

    let swiftUIColor: [CGColor] = [
      UIColor(red: 0/255, green: 240/255, blue: 245/255, alpha: 1).cgColor,
      UIColor(red: 0/255, green: 5/255, blue: 140/255, alpha: 1).cgColor
    ]
    
    let swiftColor: [CGColor] = [
    UIColor(red: 248/255, green: 138/255, blue: 54/255, alpha: 1).cgColor,
    UIColor(red: 253/255, green: 32/255, blue: 32/255, alpha: 1).cgColor
    ]
    override func viewDidLoad() {
        super.viewDidLoad()
        view.layer.addSublayer(logoLayer)
    
        startPathAnimation()
        startFillColorAnimation()
        fillGradientColor(colors: swiftColor)
    }
    
    func fillGradientColor(colors: [CGColor]) {
      let gradient = CAGradientLayer(layer: logoLayer)
      gradient.frame = swiftPath.bounds
      gradient.colors = colors
      logoLayer.addSublayer(gradient)
    }

    🤪 CAGradientLayer cover the CAShapeLayer.

    🤪 CAGradientLayer cover the CAShapeLayer.

    To fix CAGradientLayer cover the Swift logo, We need to clip mask before addSublayer.

    func fillGradientColor(colors: [CGColor]) {
      let gradient = CAGradientLayer(layer: logoLayer)
      gradient.frame = swiftPath.bounds
      gradient.colors = colors
      //Shape Mask!
      let shapeMask = CAShapeLayer()
      shapeMask.path = swiftPath.cgPath
      gradient.mask = shapeMask
      logoLayer.addSublayer(gradient)
    }

    Tada~ 😎 Looks great!

    Tada~ 😎 Looks great!

    Ok. Almost done! Let’s fill gradient color.

    override func viewDidLoad() {
      super.viewDidLoad()
      view.layer.addSublayer(logoLayer)
    
      startPathAnimation()
      startFillColorAnimation()
      fillGradientColor(colors: [UIColor.clear.cgColor, UIColor.clear.cgColor])
    }
    
    func startPathAnimation() {
      let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
      pathAnimation.fromValue = 0
      pathAnimation.toValue = 1
      pathAnimation.duration = 2
      pathAnimation.isRemovedOnCompletion = false
      pathAnimation.fillMode = .forwards
      logoLayer.add(pathAnimation, forKey: "line")
    }
    
    func startFillColorAnimation() {
      let fillColorAnimation: CABasicAnimation = CABasicAnimation(keyPath: "fillColor")
      fillColorAnimation.duration = 1
      fillColorAnimation.beginTime = CACurrentMediaTime() + 2
      fillColorAnimation.fromValue = UIColor.clear.cgColor
      fillColorAnimation.toValue = UIColor.red.cgColor
      fillColorAnimation.fillMode = .forwards
      fillColorAnimation.isRemovedOnCompletion = false
      logoLayer.add(fillColorAnimation, forKey: "fill")
    }
    
    func fillGradientColor(colors: [CGColor]) {
      let gradient = CAGradientLayer(layer: logoLayer)
      gradient.frame = swiftPath.bounds
      gradient.colors = colors
      //Shape Mask!
      let shapeMask = CAShapeLayer()
      shapeMask.path = swiftPath.cgPath
      gradient.mask = shapeMask
      logoLayer.addSublayer(gradient)
    
      //Start Animation
      startGradientAnimation(gradientLayer: gradient)
    }
    
    func startGradientAnimation(gradientLayer: CAGradientLayer) {
      let colorAnimation : CABasicAnimation = CABasicAnimation(keyPath: "colors")
      colorAnimation.duration = 2
      colorAnimation.beginTime = CACurrentMediaTime() + 3
      colorAnimation.fromValue = swiftColor
      colorAnimation.toValue = swiftUIColor
      colorAnimation.isRemovedOnCompletion = false
      colorAnimation.fillMode = .forwards
      gradientLayer.add(colorAnimation, forKey: "colors")
    }

    All done!

    All done!

    Thank you for reading my article. If you find any awkward expressions, I would appreciate your advice.

     

    I want to say that Thank you for review this post!

    Divjjot Singh helps me to improve my English writing skills. Thank you!

  • How to display the temperature with unit?

    How to display the temperature with unit?

    In this post, I’ll share how to display the temperature with unit using the MeasurementFormatter.

    MeasurementFormatter

    let numFormatter = NumberFormatter()
    numFormatter.maximumFractionDigits = 0
    
    let measureFormatter = MeasurementFormatter()
    measureFormatter.numberFormatter = numFormatter
    
    let kelvin: Double = 294
    var temperature: String = ""
    
    let kelvinTemperature = Measurement(
        value: kelvin,
        unit: UnitTemperature.kelvin
    )
    
    //temperature is automatically changed the celcius / farenheit depending on locale.
    temperature = measureFormatter.string(from: kelvinTemperature)
    
    //70°F
    print(temperature)

     

    UnitStyle

    //70 degrees Fahrenheit
    measureFormatter.unitStyle = .long
    //70°F
    measureFormatter.unitStyle = .medium
    //70°
    measureFormatter.unitStyle = .short

    The default unitStyle is medium. You can set the three different unitStyle.

    weather.PNG

    Apple Weather App

    The unitStyle is short.

  • 4 Modern iOS Animation Patterns – Launch, Loading, Transition, and Interruptible

    4 Modern iOS Animation Patterns – Launch, Loading, Transition, and Interruptible

    I had presented about iOS animations at LetSwift conference last year. I classified the animations by researching the modern iOS app. There are 4 modern animation patterns.

    • Launch Animation

    • Loading Animation

    • View Transition

    • Interruptible Animation

    Before look at the animation patterns, Let’s take a look principle of animation. This principle is helping you when to decide the easing functions on your animation code.

    The principle of the animation

    The Illusion of Life: Disney Animation

    The Illusion of Life: Disney Animation

    In 1981, Frank Thomas and Ollie Johnston define the twelve principles of animations. I select the 4 principles which can reflect UI animation. These principles affect the easing functions in the Animation framework.

    The core animation framework has an easing function. We can set the easeIn, easeInOut, easeOut, and linear with duration time. Keep in mind these principles, I’ll show the examples and guides about easing function.

    This principle can reflect the launch animation, view transition and morphing icons.

    The secondary action principle reflects the physics effect, keyFrame animation, and interruptible animation.

    Easing functions

    easing.png

    Robert Penner is the creator of the easing function. It is widely used in various programming languages. The easing functions are basically inspired by twelve principles of animations. Let’s look at which easing function are suitable for UI.

    uber app

    uber app

    Look at Side Menu. The speed of showing and hiding the menu is different. Isn’t it?
    Here is my guide about the easing function.

    • Use ease-out when the view will appear.

      • duration 150ms – 350ms

    • Use ease-in or linear when the view will disappear.

      • duration 100ms – 150ms

     

    Modern iOS Animation

    Launch Animation

    The launch animation is the first impression and gives a delightful experience to the user. Technically, an iOS app is fetching data from the server, and It takes time to show the interface. So the fancy iOS apps use the launch animations while loading data.

    twitter.gif

    nike.gif

    uber.gif

    launch.gif

    I make the launch animation. I’ll post about how to make your launch animation.

    Loading Animation

    The loading animation displayed on the placeholder does not cover the screen, so it looks much cleaner.

    fbLoading.gif

    instagram.gif

    left_right_loading.gif

    I make the loading animation. I’ll post about how to make your loading animation.

    View Transition

    ViewTransition gives seamless experience compare to push view controller and present view controller, which is the default iOS presenting style. Technically you can implement your view transition style using UIViewControllerAnimatedTransitioning. I’ll post about UIViewControllerAnimatedTransitioning.

    zenly.gif

    nike.gif

    pinterest.gif

    instagram.gif

    Interruptible Animation

    You can see how Interruptible Animation works on the Apple Maps app. When you swipe up and down, then It will be starting Animation to expand the content. Interruptible Animation allows canceling while animating. Apple introduces this feature on iOS 10, and it called UIPropertyAnimator. I’ll also post about it soon.

    applemap.gif

     

    Conclusion

    I introduce the modern iOS animation styles. There are four kinds of patterns, and I’ll post how to implement these four patterns using CoreAnimation. If you want to get more information, then please look at references.

    References

    Google Fundamentals Design and UX

    Apple Core Animation Guide

    Disney 12 Principle Animations

    https://easings.net

    Understand-the-12-principles-of-animation

    Books

    Raywenderlich iOS Animation Book

    iOS Core Animation: Advanced Techniques

    Youtube

    Coding Math

    WWDC

    2017 Advances in UIKit Animations and Transitions

  • How to remove text insets on UITextView?

    How to remove text insets on UITextView?

    Default UITextView has text insets, unlike the UILabel.

    Default UITextView has text insets, unlike the UILabel.

    How to remove the insets on UITextView like an UILabel?

    UITextView

    UITextView

    On the storyboard, select the UITextView and remove the Scrolling Enabled.

    @IBOutlet weak var textView: UITextView!
    override func viewDidLoad() {
        super.viewDidLoad()
        textView.textContainer.lineFragmentPadding = 0
        textView.textContainerInset = .zero
    }

    removeInset.png

    UITextView which is removed text insets will look like an UILabel.

    Thanks for reviewing my post

    Divjjot Singh ( 신승훈 )

  • Introduction to Table

    Introduction to Table

    Last month I made the Table library. I inspired by javascript console.table.

     

    What is the Table?

    The Table is a helper function to print the tabulation data bypassing the Any data! [e.g., 1d array, 2d array, and dictionary]. I’m sure if you practice coding interviews, it helps you a lot. You don’t need to struggle for checking results using a build-in print function! 

     

    Examples

    The Table can print the tabulation data. It also supports the iPad playground.

    print(
        table: ["Good", "Very Good", "Happy", "Cool!"], 
        header: ["Wed", "Thu", "Fri", "Sat"]
    )
    
    //Result
    +----+---------+-----+-----+
    |Wed |Thu      |Fri  |Sat  |
    +----+---------+-----+-----+
    |Good|Very Good|Happy|Cool!|
    +----+---------+-----+-----+
    
    print(
        table: [
            "1": 1, 
            2: "Hellow?", 
            1.2: 0, 
            "I'm Table": [1, 2, 3, 2, 1]], 
        header: [
            "key", "value"
        ]
    )
    
    //Result
    +---------+---------------+
    |key      |value          |
    +---------+---------------+
    |2        |Hellow?        |
    +---------+---------------+
    |I'm Table|[1, 2, 3, 2, 1]|
    +---------+---------------+
    |1.2      |0              |
    +---------+---------------+
    |1        |1              |
    +---------+---------------+
    
    print(table: [
        [1, 2, 3], 
        [4, 5, 6], 
        [7, 8, 9, 10]
    ])
    
    //Result
    +-+-+-+--+
    |1|2|3|  |
    +-+-+-+--+
    |4|5|6|  |
    +-+-+-+--+
    |7|8|9|10|
    +-+-+-+--+
    

    iPad.PNG

     

    Inside the Table Library

    The declaration of function is similar to standard Swift print function.

    //Standard print
    func print(
        _ items: Any..., 
        separator: String = " ", 
        terminator: String = "\n"
    )
    
    //Table print
    @discardableResult func print(
        table data: Any,
        header: [String]? = nil,
        distribution: TableSpacing = .fillProportionally,
        terminator: String = ""
    ) -> String
    

    The difference is that it is not a variadic function. It take the one data type and then print the tabulation of given data.

     

    How to check the given data type?

    It use the Mirror to check the given data type. It is useful to check the type of any data.

    A representation of the substructure and display style of an instance of any type.

    https://developer.apple.com/documentation/swift/mirror
    let mirrorObj = Mirror(reflecting: data)
    
    //Check one dimensional array
    if mirrorObj == [Any].self {
    }
    //Check two dimensional array
    else if mirrorObj == [[Any]].self {
    }
    //Check Dictionary
    else if mirrorObj == [AnyHashable: Any].self {
    }
    

     

    Check the Item Width

    To display the tabulation of data, It needed item width in data elements. The table cell’s width is set by the longest item width.

    private func tableInfo<Item: LosslessStringConvertible>(
    data: [Item]) -> (
        numberOfItem: Int,
        maxWidth: Int,
        widthInfo: [Int: Int]
        ) {
        let stringData = data.map { String($0) }
        let maxWidth = stringData.sorted { 
            $0.count > $1.count 
        }.first!.count
        var maxWidthDict: [Int: Int] = [:]
        for (index, item) in stringData.enumerated() {
            maxWidthDict[index] = item.count
        }
        return (
            numberOfItem: stringData.count, 
            maxWidth: maxWidth, 
            widthInfo: maxWidthDict
        )
    }
    

    The tableInfo function return the informations of data. I use the LosslessStringConvertible protocols to get the item width by checking the characters of string.

    For example, the integer value 1050 can be represented in its entirety as the string “1050”.

    https://developer.apple.com/documentation/swift/losslessstringconvertible

    This function didn’t considering the Unicode block so far. If you set the CJK(Chinese, Japanese, and Korean) characters then table layout will be broken. I’m going to solve it by using Unocode-Box-Drawing next time.

     

    Unit Test

    Apple tests the print function using TextOutputStream.

    //Declaration of print function by Apple
    func print<Target>(
        _ items: Any..., 
        separator: String = " ", 
        terminator: String = "\n", 
        to output: inout Target
    ) where Target : TextOutputStream
    

    The TextOutputStream is a protocol. The String type already conforms to TextOutputStream. So If you pass the reference of String at to in print function, The output of print will be written into String.

    //https://github.com/apple/swift/blob/master/test/stdlib/Print.swift
    PrintTests.test("StdoutUTF8") {
      expectPrinted("µ", "\u{00B5}")
    }
    
    PrintTests.test("Varargs") {
      var s0 = ""
      print("", 1, 2, 3, 4, "", separator: "|", to: &s0)
      expectEqual("|1|2|3|4|\n", s0)
    
      var s1 = ""
      print(1, 2, 3, separator: "\n", terminator: "===", to: &s1)
      expectEqual("1\n2\n3===", s1)
    
      var s2 = ""
      print(4, 5, 6, separator: "\n", to: &s2)
      expectEqual("4\n5\n6\n", s2)
    
      var s3 = ""
      print("", 1, 2, 3, 4, "", separator: "|", to: &s3)
      expectEqual("|1|2|3|4|\n", s3)
    }
    

    I wrote the unit tests code by checking the result of function.

    func test_1DArray_Of_String_with_header() {
      let output = print(
      table: ["Good", "Very Good", "Happy", "Cool!"],
      header: ["Wed", "Thu", "Fri", "Sat"]
      )
      let expected = """
      +----+---------+-----+-----+
      |Wed |Thu      |Fri  |Sat  |
      +----+---------+-----+-----+
      |Good|Very Good|Happy|Cool!|
      +----+---------+-----+-----+
    
      """
      XCTAssertEqual(output, expected)
    }
    
    func test_2DArray_Of_Int_With_Different_Columns() {
        let output = print(
          table: [
            [1, 2, 3], 
            [4, 5, 6], 
            [7, 8, 9, 10]
          ]
        )
      let expected = """
      +-+-+-+--+
      |1|2|3|  |
      +-+-+-+--+
      |4|5|6|  |
      +-+-+-+--+
      |7|8|9|10|
      +-+-+-+--+
    
      """
      XCTAssertEqual(output, expected)
    }
    

    Swift Over Coffee S2E4: Erica vs the World

    Paul Hudson(HackingWithSwift.com) introduces the Table library on the Swift Over Coffee PodCast Episode S2E4.

    In this episode: WWDC goes WFH, Swift gets some inspiration from JavaScript, and we review your awesome Breathe app submissions.

     

    What’s the next step?

    I’m going to support more types!

    • tuple

    • decodable / encodable

    • custom data type

    • emoji / unicode

  • What’s new on scrollView?

    What’s new on scrollView?

    In Xcode 11, the scroll view has two new things, which are the Content Layout Guide and Frame Layout Guide.

    It’s a very convenient way to set content size for scrollView.

    Let’s check how to use it on the storyboard.

    scrollView.png

    What is the Content Layout Guide?

    It is the size of the content. For example, if your scrollView is enabled vertical scrolling only, then set the subviews constraints relative to the Content Layout Guide.

    viewConstraintStep1.png

    viewConstraintStep2.png

    What is the Frame Layout Guide?

    It is a fixed size of the content. For example, if scrollView is enabled vertical only, then just set the Frame Layout Guide’s width constraint and leave your height constraint.

    viewConstraintStep3.png

    How to resolve the constraint warnings?

    The above steps is an essential for scrollView with its subView. However Storyboard may still complain.

    constraintProblem.png

    To solve the constraint issue, change the intrinsic size of the scroll views subView.

    constraintSolve.png

    Add stackView

    For scrolling the contents, I added stackView with listViews.

    scrolling.gif

    Thanks for reviewing my post

    Shai Mishali

    Navati is having tea

    Bart Pang

  • Data Structures and Algorithms for Coding Interviews – Essential Summary

    Data Structures and Algorithms for Coding Interviews – Essential Summary

    The coding interview is hard because We have to remember the basic data structures and algorithms. For me, I received masters degree of computer science seven years ago. Most of the tech companies require the coding interview when you apply for a job. So I decided to summarize the data structure and algorithm.

    Here is the list, and I’ll write the basic concept and will be solving problems using Swift

    Complexity

    • Time Complexity

    • Space Complexity

    Data Structures

    • Stack

    • Queue

    • Circular Queue

    • Linked List

    • Doubly Linked List

      1. Reverse Linked List

    • Hash Table

    • Tree

    • Binary Tree

      1. BFS

      2. DFS

        1. Pre-Order

          1. In-Order

          2. Post-Order

      3. Binary Search Tree [Ordered Binary Tree]

    • Dictionary

    • Set

    • Graph

    • Directed

      1. Undirected

      2. Graph using an Adjacency Matrix

      3. Graph using an Adjacency List and Set

      4. Depth First

      5. Breath First

      6. Topological Sort

      7. Weighted Graph

      8. Negative Weighted Graph

    Algorithms

    • Stack

      • Match parenthesis in an expression

      • find the minimum element in a expression

      • stack in constant time

    • Sorting

      • Selection Sort

      • Insertion Sort

      • Bubble Sort

      • Shell Sort

      • Merge Sort

      • Quick Sort

    • Search

      • Linear Search [Brute Force]

      • Binary Search [Sorted List]

    • Binary Tree

      • Find the minimum value in a Binary Search Tree

      • Find the maximum depth of a Binary Tree

      • Mirror a Binary Tree

      • Count the number of structurally unique binary tree possible

      • print all nodes within a range in a binary search tree

      • check if a binary tree is a binary search tree

      • check if a path from toot to leaf node sums up to a certain value

      • print all paths from the root to the leaf nodes

      • find the least common ancestor for 2 nodes

    • Heap [Priority Queue]

      • The Binary Heap

        1. Minimum Heap

        2. Maximum Heap

        3. Balanced Binary Search Tree

        4. An array or A list

        5. Insert and remove from a Heap

        6. Heapify

        7. Heap Sort

        8. Merge K sorted lists into one sorted array

        9. maximum element in a minimum heap and K largest elements in a stream

        10. Find the median In a stream of elements

    • Graph

      • Shortest path algorithm

      • Shortest path in a weighted graph

      • Dijkstra’s Algorithm [Greedy Algorithm]

      • Bellman Ford Algorithm [Shortest path in negative weighted graph] [Greedy Algorithm]

      • Dealing with negative cycles in the weighted graph [Bellman Ford Algorithm]

      • Prim’s Algorithm for a Minimal Spanning Tree [Undirected Graph] [Greedy Algorithm]

      • Kruskal’s Algorithm for a Minimal Spanning Tree for Forest [Priority Queue] [Connected / Unconnected]

      • Find the shortest path In a weight graph

      • Design A course schedule considering pre request for courses

    General Programming Problem

    • Basic Operation

    • Bit Manipulation

      • Set and Get n-th Bit

      • Print bits in Integer

      • Count the number of 1 bits

      • Reverse the bits in an Integer

    • Recursion

      • Find All subsets of A given set

      • Check whether 2 binary tree are the same

      • Paint Fill

      • Build A car given tasks and dependencies

      • Find all anagrams of a given word

      • Find a path a rat can travel through a maze

      • place 8 queens on a chess board

    • Palindrome

    • Find Distance

    • Run Length Encoding and Decoding

    • Game of Life

    • Break A Document Into Chunks

    • Add Two Numbers Represented by their Digits

    • Sudoku Validator

    • Incrementing A Number

     

    Thanks for reviewing my post

    Divjjot Singh ( 신승훈 )

  • How to render xib on Storyboard?

    How to render xib on Storyboard?

    When you create the custom view with xib and then set the custom view on Storyboard but if It has not appeared. How can you solve the rendering issue?

    I stuck in similar issues on Xcode 11.

    xcode 11 said -> Failed to render and update auto layout the agent threw an exception

    Here is my solution and I hope it helps you!

    customView.png

    import UIKit
    
    @IBDesignable
    class XibView: UIView {
        let className = String(describing: XibView.self)
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setupNib()
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupNib()
        }
    
        private func setupNib() {
            guard let nib = loadNib() else { return }   
            nib.translatesAutoresizingMaskIntoConstraints = false
            addSubview(nib)
            NSLayoutConstraint.activate([
                nib.leadingAnchor.constraint(equalTo: self.leadingAnchor),
                nib.trailingAnchor.constraint(equalTo: self.trailingAnchor),
                nib.topAnchor.constraint(equalTo: self.topAnchor),
                nib.bottomAnchor.constraint(equalTo: self.bottomAnchor)
            ])
        }
    
        func loadNib() -> UIView? {
            let bundle = Bundle(for: Self.self)
            return bundle.loadNibNamed(String(describing: Self.self), owner: self, options: nil)?.first as? UIView
        }
    }

    image-asset.png

  • How to enable syntax highlighting for Swift on Squarespace

    How to enable syntax highlighting for Swift on Squarespace

    Let’s enabling syntax highlighting for Swift

    The Squarespace supports syntax highlighting for HTML, CSS, and Javascript.

    But It does not support other programming languages.

    To enable it, We can choose the syntax highlighting plugins.

    I recommend PrismJS

    Download PrismJS css and javascript

    prismjs_compressionLevel.png

    Select PrismJS option before downloading it.

    • Compression level to Minified version

    • Language for Swift

    • Plugins (e.g., line numbers)

    prismjs_download.png

    Download the JS and CSS. That’s it.

    Copy and Paste it into the Squarespace

    EditingBlog.png

    Go to the setting Pages > Select your blog page (e.g., Posts)

    CodeInjection.png

    Go to Advanced tap and Copy and Paste the CSS and Javascript code into the Post Blog Item Code injection

    <style>
    <!-- Paste Your PrismJS CSS -->
    </style>
    <script>
    /*
    Paste your PrismJS Javascript
    */
    </script>

    Now We can syntax highlighting for Swift using Markdown

    markdown.png.jpeg

    let greeting = "Welcome to Shawn Baek's blog!"
    print(greeting)