Swift: Constraints incorrect when device is started in landscape

I currently have an application where I programmatically set the constraints. The problem occurs when the app is started in landscape mode. When the app is started in landscape mode, the size of the UIViews width and height extend past the screen. However, when the app is started in portrait mode, the app is fine, and it keeps its constraints properly when rotating. This seems to only be a problem when opening the app in landscape. Here is my code and screen shots:

I currently have an application where I programmatically set the constraints. The problem occurs when the app is started in landscape mode. When the app is started in landscape mode, the size of the UIViews width and height extend past the screen. However, when the app is started in portrait mode, the app is fine, and it keeps its constraints properly when rotating. This seems to only be a problem when opening the app in landscape. Here is my code and screen shots:

  func setUpGameBoard(){
    let width =  UIScreen.main.bounds.width
   let gameBoard = Gameboard(frame: .zero, mainVC: self)
    self.view.addSubview(gameBoard)
    gameBoard.translatesAutoresizingMaskIntoConstraints = false
    gameBoard.widthAnchor.constraint(equalToConstant: width).isActive = true
    gameBoard.heightAnchor.constraint(equalToConstant: width).isActive = true
    gameBoard.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    gameBoard.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

Here it is when started upright, there is no problems when rotating.


Keeping your JavaScript code clean forever and scalable

Keeping your JavaScript code clean forever and scalable

Writing clean code and scalable is what you must know and do in order to call yourself a professional developer. Following these guidelines help to Keep your JavaScript code clean forever and scalable.

JavaScript has its origins in the early web. Starting out as a scripting language, it has now evolved into a fully fledged programming language with support for server-side execution.

Modern web applications rely heavily on JavaScript, especially single-page applications (SPAs). With emerging frameworks like React, AngularJS, and Vue.js, web apps are mainly built with JavaScript.

Scaling these applications — frontend equally as backend — can be quite tricky. With a mediocre setup, you will eventually hit limitations and get lost in a sea of confusion. I want to share a couple of small tips that will help you write clean code in an efficient way.

This article is geared towards JavaScript developers of any skill level. However, developers with at least intermediate knowledge of JavaScript will benefit most from these tips.


1. Isolate your code

The most important thing I can recommend to keep a codebase clean and readable is having specific chunks of logic (usually functions) separated by topic. If you write a function, the function should default to having only one purpose and should not do multiple things at once.

Also, you should avoid causing side effects, meaning in most cases, you should not change anything that is declared outside your function. You receive data into functions with parameters; everything else should not be accessed. If you wish to get something out of the function, return new values.

2. Modularization

Of course, you can group multiple functions into one module (and/or class, if you wish) if these functions are used in a similar way or do similar things. For example, if you have many different calculations to do, split them up into isolated steps (functions) that you can chain. However, these functions can all be declared in one file (module). Here is the example in JavaScript:

function add(a, b) {
    return a + b   
}

function subtract(a, b) {
    return a - b   
}

module.exports = {
    add,
    subtract
}

const { add, subtract } = require('./calculations')

console.log(subtract(5, add(3, 2))

If you are writing frontend JavaScript, definitely make use of default exports for the most important items and named exports for secondary items.

3. Prefer multiple parameters over single object parameters

When declaring a function, you should always prefer multiple parameters over one parameter that expects an object:

// GOOD
function displayUser(firstName, lastName, age) {
    console.log(`This is ${firstName} ${lastName}. She is ${age} years old.`)
}

// BAD
function displayUser(user) {
    console.log(`This is ${user.firstName} ${user.lastName}. She is ${user.age} years old.`)
}

The reason behind this is that you know exactly what you need to pass to the function when you look at the first line of the function declaration.

Even though functions should be limited in size — doing only one job — it may happen that functions grow bigger in size. Scanning through the function body for the variables you need to pass (that are nested inside an object) will take you more time. Sometimes it might seem easier to just use the whole object and pass it to the function, but to scale your application, this setup will definitely help.

There is a certain point where declaring specific parameters does not make sense. For me, it is above four or five function parameters. If your function grows that big, you should pivot to use object parameters.

The main reason here is that parameters need to be passed in a specific order. If you have optional parameters, you need to   pass undefined or null. With object parameters, you can simply pass the whole object, where order and undefined values do not matter.

4. Destructuring

Destructuring is a nice tool that was introduced with ES6. It lets you grab specific fields from an object and assign it to a variable immediately. You can use this for any kind of object or module.

// EXAMPLE FOR MODULES
const { add, subtract } = require('./calculations')

It does make sense to only import the functions you need to use in your file instead of the whole module, and then access the specific functions from it. Similarly, when you decide that you definitely need an object as function parameter, use destructuring as well. This will still give you the overview of what is needed inside the function:

function logCountry({name, code, language, currency, population, continent}) {
    let msg = `The official language of ${name} `
    if(code) msg += `(${code}) `
    msg += `is ${language}. ${population} inhabitants pay in ${currency}.`
    if(contintent) msg += ` The country is located in ${continent}`
}

logCountry({
    name: 'Germany',
    code: 'DE',
    language 'german',
    currency: 'Euro',
    population: '82 Million',
})

logCountry({
    name: 'China',
    language 'mandarin',
    currency: 'Renminbi',
    population: '1.4 Billion',
    continent: 'Asia',
})

As you can see, I still know what I need to pass to the function — even if it is wrapped in an object. To solve the problem of knowing what is required, see the next tip!

(By the way, this also works for React functional components.)

5. Use default values

Default values for destructuring or even basic function parameters are very useful. Firstly, they give you an example of what value you can pass to the function. Secondly, you can indicate which values are required and which are not. Using the previous example, the full setup for the function could look like this:

function logCountry({
    name = 'United States', 
    code, 
    language = 'English', 
    currency = 'USD', 
    population = '327 Million', 
    continent,
}) {
    let msg = `The official language of ${name} `
    if(code) msg += `(${code}) `
    msg += `is ${language}. ${population} inhabitants pay in ${currency}.`
    if(contintent) msg += ` The country is located in ${continent}`
}

logCountry({
    name: 'Germany',
    code: 'DE',
    language 'german',
    currency: 'Euro',
    population: '82 Million',
})


logCountry({
    name: 'China',
    language 'mandarin',
    currency: 'Renminbi',
    population: '1.4 Billion',
    continent: 'Asia',
})

Obviously, sometimes you might not want to use default values and instead throw an error if you do not pass a value. Oftentimes, however, this is a handy trick.

6. Data scarcity

The previous tips lead us to one conclusion: do not pass around data that you don’t need. Here, again, it might mean a bit more work when setting up your functions. In the long run, however, it will definitely give you a more readable codebase. It is invaluable to know exactly which values are used in a specific spot.

7. Line and indentation limit

I have seen big files — very big files. In fact, over 3,000 lines of code. Finding chunks of logic is incredibly hard in these files.

Therefore, you should limit your file size to a certain number of lines. I tend to keep my files below 100 lines of code. Sometimes, it is hard to break up files, and they will grow to 200–300 lines and, in rare occasions, up to 400.

Above this threshold, the file gets too cluttered and hard to maintain. Feel free to create new modules and folders. Your project should look like a forest, consisting of trees (module sections) and branches (groups of modules and module files). Avoid trying to mimic the Alps, piling up code in confined areas.

Your actual files, in comparison, should look like the Shire, with some hills (small levels of indentation) here and there, but everything relatively flat. Try to keep the level of indentation below four.

Maybe it is helpful to enable eslint-rules for these tips!

8. Use prettier

Working in a team requires a clear style guide and formatting. ESLint offers a huge ruleset that you can customize to your needs. There is also eslint --fix, which corrects some of the errors, but not all.

Instead, I recommend using Prettier to format your code. That way, developers do not have to worry about code formatting, but simply writing high-quality code. The appearance will be consistent and the formatting automatic.

9. Use meaningful variable names

Ideally, a variable should be named based on its content. Here are some guidelines that will help you declare meaningful variable names.

Functions

Functions usually perform some kind of action. To explain that, humans use verbs — convert or display, for example. It is a good idea to name your functions with a verb in the beginning, e.g., convertCurrency or displayUserName.

Arrays

These will usually hold a list of items; therefore, append an s to your variable name. For example:

const students = ['Eddie', 'Julia', 'Nathan', 'Theresa']

Booleans

Simply start with is or has to be close to natural language. You would ask something like, “Is that person a teacher?” → “Yes” or “No.” Similarly:

const isTeacher = true // OR false

Array functions

forEachmapreducefilter, etc. are great native JavaScript functions to handle arrays and perform some actions. I see a lot of people simply passing el or element as a parameter to the callback functions. While this is easy and quick, you should also name these according to their value. For example:

const cities = ['Berlin', 'San Francisco', 'Tel Aviv', 'Seoul']
cities.forEach(function(city) {
...
})

IDs

Oftentimes, you have to keep track of the ids of specific datasets and objects. When ids are nested, simply leave it as id. Here, I like to map MongoDB _id to simply id before returning the object to the frontend. When extracting ids from an object, prepend the type of the object. For example:

const studentId = student.id
// OR
const { id: studentId } = student // destructuring with renaming

An exception to that rule is MongoDB references in models. Here, simply name the field after the referenced model. This will keep things clear when populating references documents:

const StudentSchema = new Schema({
    teacher: {
        type: Schema.Types.ObjectId,
        ref: 'Teacher',
        required: true,
    },
    name: String,
    ...
})

10. Use async / await where possible

Callbacks are the worst when it comes to readability — especially when nested. Promises were a nice improvement, but async/await has the best readability, in my opinion. Even for beginners, or people coming from other languages, this will help a lot. However, make sure you understand the concept behind it and do not mindlessly use it everywhere.

11. Module import order

As we saw in tips 1 and 2, keeping logic in the right place is key to maintainability. In the same way, how you import different modules can reduce confusion in your files. I follow a simple structure when importing different modules:

// 3rd party packages
import React from 'react'
import styled from 'styled-components'

// Stores
import Store from '~/Store'

// reusable components
import Button from '~/components/Button'

// utility functions
import { add, subtract } from '~/utils/calculate'

// submodules
import Intro from './Intro'
import Selector from './Selector'

I used a React component as an example here since there are more types of imports. You should be able to adapt that to your specific use case.

12. Get rid of console

console.log is a nice way of debugging — very simple, quick, and does the job. Obviously, there are more sophisticated tools, but I think every developer still uses it. If you forget to clean up logs, your console will eventually end up a giant mess. Then there is logs that you actually want to keep in your codebase; for example, warning and errors.

To solve this issue, you can still use console.log for debugging reasons, but for lasting logs, use a library like loglevel or winston. Additionally, you can warn for console statements with ESLint. That way you can easily globally look for console... and remove these statements.


Cool, isn’t it?

Following these guidelines help to Keep your JavaScript code clean forever and scalable. Are there any tips you find particularly useful? Let us know in the comments what you will include in your coding workflow, and please share any other tips you use to help with code structure!

Thanks for reading, Keep visiting. Hope this post will surely help and you! Please share if you liked it!

Related Articles: Keeping your Vue.js code Clean

Build a Stopwatch app with SwiftUI

Build a Stopwatch app with SwiftUI

In this article I will show you how to build a stopwatch app using SwiftUI. In this post I will show you how to create custom views using SwiftUI as well as some basic layout and using “ObjectBinding”.

I know we are building a stopwatch app, but I am not going to go through the actual StopWatch code logic as I feel that is out of scope for this tutorial. This tutorial is more about building the apps UI with SwiftUI.

In the above picture you can see what the app will look like when we are done. It is nothing special, but it is functional.

When the app is complete, you will be able to start the stop watch, record laps times(this will only be in memory), pause the stop watch and reset it.

So now that we know what it needs to look like and what the functionality is, we can start building it.

Step 1: Add the StopWatch class to your project

I created this class for this tutorial only. I would not classify it as production ready as it has not been tested properly, the code is also not too great. It is for demonstration purposes only.

You can find the StopWatch class here. Or you can download the gist here.

Step 2: Add the timer Text()

In your main ContentView inside the body variable we need to add a VStack. Your code should look like this:

struct ContentView : View {
    @ObjectBinding var stopWatch = StopWatch()
    
    var body: some View {
        VStack {
            // Code here
        }
    }
}

That VStack will hold all of our UI. Now that we have our VStack we can add in our Text view to display the timer text.

With SwiftUI the parent view cannot force a size on the child/children view, so we will need to do most of the styling on the Text view that we add. Add the following code inside the VStack that we added in just now.

Text(self.stopWatch.stopWatchTime)
    .font(.custom("courier", size: 70))
    .frame(width: UIScreen.main.bounds.size.width,
           height: 300,
           alignment: .center)

In the above code we are creating a new Text view. We set the default text to be 00:00:00 which will be updated later on with the proper value.

After that we start with the styling. I changed the font to courier, this works better as it is a monospace font, when I used the standard system font the text would shake because it was changing all the time. We also set the size to be 70 so that it is nice and big. The next thing we do is update the frame. We want the width to be the full width of the screen but we also want it to be quite tall, so we set the height to 300. Technically you can leave the .center alignment out as that is the default setting.

Your app should now look like this:

Not exactly what we want, but it is a start.

Step 3: Create the buttons view

Before we carry on with the layout, we need to create the buttons. This will be a new custom view. The buttons functionality as well as text will change depending on the state of the stopwatch.

For example, when the timer is stopped, we will have two buttons, one will be to reset the timer and the other will be to start the timer. If the timer is busy timing, those buttons will change to a lap button and a pause button.

Because the app is super small, I have put the logic in the button. If the app was bigger, I would strip out the logic from the button and use something else to create the button that I need based on the parameters I pass to it.

What do the buttons require?

Each button needs to take in two actions and two strings. They also need to have a color and they need to know if the timer is paused or not.

The code

To do this, create a new struct called StopWatchButton and have it conform to the View protocol as below:

struct StopWatchButton : View {
    var body: some View {
        // Buttons coming soon
    }
}

We can now add in the properties just above the body property.

Change your struct to look like this now:

struct StopWatchButton : View {
    var actions: [() -> Void]
    var labels: [String]
    var color: Color
    var isPaused: Bool    var body: some View {
        // Buttons coming soon
    }
}

Great, we can now add the button logic in the body.

The first thing that we need to add is a button width variable in the body. This value is quite random, but it works for our needs.

Your body property should now look like this:

var body: some View {
    let buttonWidth = (UIScreen.main.bounds.size.width / 2) - 12
}

This will give an error but don’t worry, we will sort that out now.

We will now create the button view. It is not too complicated. A basic Button in SwiftUI takes two arguments, one is the action and the other is the label view. In our action and label parameters we will check if the timer is paused and based on that we will know what function to call and what Text view we need to display.

Update your body variable to look like the below:

var body: some View {
    let buttonWidth = (UIScreen.main.bounds.size.width / 2) - 12
    
    return Button(action: {
            if self.isPaused {
                self.actions[0]()
            } else {
                self.actions[1]()
            }
        }) {
            if isPaused {
                Text(self.labels[0])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            } else {
                Text(self.labels[1])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            }
        }
        .background(self.color)
    }
}

In the above code you can see what we are doing. In the action section(the first closure) we check the isPaused property. If it is true then we use the first action in our actions array, otherwise we use the second action.

The same is true for the label. If isPaused is true, we will use the first string from our labels array, otherwise we use the second string.

Other than that, each Text view has the same styling, we could create our own custom text view for that, but this is pretty simple so I don't see much of a need for that right now. If we were going to use text views that were the same as these elsewhere then I would definitely create a custom text view.

One thing to note is how the Text view frame is being set and not the buttons frame. As I mentioned earlier, SwiftUI requires us to set the frame on the child view as the parent cannot tell the child what to do.

The last thing that we do is we set the background color for the button.

The final code for the StopWatchButton should look like this:

struct StopWatchButton : View {
    var actions: [() -> Void]
    var labels: [String]
    var color: Color
    var isPaused: Bool
    
    var body: some View {
        let buttonWidth = (UIScreen.main.bounds.size.width / 2) - 12
        
        return Button(action: {
            if self.isPaused {
                self.actions[0]()
            } else {
                self.actions[1]()
            }
        }) {
            if isPaused {
                Text(self.labels[0])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            } else {
                Text(self.labels[1])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            }
        }
        .background(self.color)
    }
}

Step 4: Adding the buttons

Ok, most of the complicated stuff is now out of our way and we can get back to laying out our UI.

The next thing that we need to do is to add the two instances of our new StopWatchButton. Before we do that we need to create an HStack that can wrap our buttons.

Update your ContentView struct to look like the below:

struct ContentView : View {
    @ObjectBinding var stopWatch = StopWatch()
    
    var body: some View {
        VStack {
            Text(self.stopWatch.stopWatchTime)
                .font(.custom("courier", size: 70))
                .frame(width: UIScreen.main.bounds.size.width,
                       height: 300,
                       alignment: .center)
            
            HStack{
                // Our buttons will go here
            }
        }
     }
 }

As you can see. Nothing much has changed except that we now have an HStack below our Text view that will display the current timers string value.

Inside that HStack you need to add the following code:

StopWatchButton(actions: [self.stopWatch.reset, self.stopWatch.lap],
                labels: ["Reset", "Lap"],
                color: Color.red,
                isPaused: self.stopWatch.isPaused())StopWatchButton(actions: [self.stopWatch.start, self.stopWatch.pause],
                labels: ["Start", "Pause"],
                color: Color.blue,
                isPaused: self.stopWatch.isPaused())

After adding that code, your app should look like this:

This might be a bit confusing. In the above code we are creating two new instances of our StopWatchButton.

As discussed earlier these buttons have four properties. The first property will be the functions that we want to call depending on the isPaused state. The first button that we create will be our Reset/Lap and our second button will be our Start/Pause button. In the image you cannot see the Lap button and the Pause button, but if you run the app and click on the Start button, you will be able to see the Lap and Pause button. Please note, if you run the app and you tap on the Lap button, nothing will happen visually. The code will be working correctly, but in the next step I will show you how to get the lap times to show up in the list.

Step 5: Displaying the lap times

This next part is pretty simple. All we have is a VStack that wraps around a Text view and a List view.

Below the HStack that we created in the previous step, add the following code:

VStack(alignment: .leading) {
    Text("Laps")
        .font(.title)
        .padding()List { 
        ForEach(self.stopWatch.laps.identified(by: \.uuid)) { (lapItem) in
            Text(lapItem.stringTime)
        }
    }
}

Now that you have added that, your app should look something like this:

Please note that these screen shots are being taken in Xcode, if you run the app, you will see the cells of the List.

Ok, so what is happening in that code. The first thing that is different is that the VStack is taking an argument for alignment. The reason that I have done this is because if we remove it, the Laps text view will be centered on the screen, and I preferred it to be on the left hand side.

Inside the VStack we add a Text view. We set the font size to be of .title size, has it is a section heading in our app. We also add padding to the Text view. This gives it a nice amount of spacing so that it is separated from the buttons above.

The final part is to add the List view. List views require a unique identifier for each cell. Unfortunately, each lapItem would not have a uniquely identifying property, so I had to add a uuid property which gets used in the ForEach. We then have access to the lapItem. We can now add in another Text view in which we can display each of the lap times that we have stored. To do this we simply access the stringTime property on the lapTime object that we have, and pass that to the Text view.

If you build and run the app now, you should be able to start the stopwatch, tap the Lap button and see the lap times show up in the bottom List. You should also be able to tap the Pause button and have the stopwatch pause, and once it is paused you should be able to tap the Reset button which will reset the stopwatch time as well as remove all the lap times from the List.

This is what the final code looks like:

import SwiftUIstruct StopWatchButton : View {
    var actions: [() -> Void]
    var labels: [String]
    var color: Color
    var isPaused: Bool
    
    var body: some View {
        let buttonWidth = (UIScreen.main.bounds.size.width / 2) - 12
        
        return Button(action: {
            if self.isPaused {
                self.actions[0]()
            } else {
                self.actions[1]()
            }
        }) {
            if isPaused {
                Text(self.labels[0])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            } else {
                Text(self.labels[1])
                    .color(Color.white)
                    .frame(width: buttonWidth,
                           height: 50)
            }
        }
        .background(self.color)
    }
}struct ContentView : View {
    @ObjectBinding var stopWatch = StopWatch()
    
    var body: some View {
        VStack {
            Text(self.stopWatch.stopWatchTime)
                .font(.custom("courier", size: 70))
                .frame(width: UIScreen.main.bounds.size.width,
                       height: 300,
                       alignment: .center)
            
            HStack{
                StopWatchButton(actions: [self.stopWatch.reset, self.stopWatch.lap],
                                labels: ["Reset", "Lap"],
                                color: Color.red,
                                isPaused: self.stopWatch.isPaused())StopWatchButton(actions: [self.stopWatch.start, self.stopWatch.pause],
                                labels: ["Start", "Pause"],
                                color: Color.blue,
                                isPaused: self.stopWatch.isPaused())
            }VStack(alignment: .leading) {
                Text("Laps")
                    .font(.title)
                    .padding()List {
                    ForEach(self.stopWatch.laps.identified(by: \.uuid)) { (lapItem) in
                        Text(lapItem.stringTime)
                    }
                }
            }
        }
    }
}

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

A guide to Object Detection with OpenCV and Swift

A guide to Object Detection with OpenCV and Swift

In this article, we’ll see how to create and launch a object detection algorithm using OpenCV and Swift

Swift has been with us for a while now, and through its iterations, it has brought to us all the features of a modern object-oriented programming language. These include optionals, generics, tuples, structs that support methods, extensions and protocols, and many more. But if your application relies on a library that’s written using C++ then you can’t count on Swift anymore. Luckily Objective-C++ is here to help us.

Since its introduction, Swift has had great interoperability with Objective-C and we will use Objective-C for bridging Swift with C++. Objective-C++ is nothing more than Objective-C with the ability to link with C++ code, and using that, in this blog post, we will create a simple app that will recognize the Toptal logo inside the image using OpenCV. When we detect that logo, we’ll open the Toptal home page.

As stated on the OpenCV web page:

"OpenCV was designed for computational efficiency and with a strong focus on real-time applications. Written in optimized C/C++, the library can take advantage of multi-core processing."
This is a great solution if you want fast to develop and reliable computer vision.

Creating the OpenCV Objective-C++ Wrapper

In this tutorial, we will design the application which will match a Toptal logo inside an image and open Toptal web page. To begin, create a new Xcode project and set up CocoaPods using pod init. Add OpenCV to Podfile pod 'OpenCV and run pod install in Terminal. Be sure to uncomment use_frameworks! statement inside Podfile.

Now, when we have OpenCV inside Xcode project, we have to connect it with Swift. Here is a quick outline of the steps involved:

Step 1: Create a new Objective-C class OpenCVWrapper. When Xcode asks you “Would you like to configure an Objective-C bridging header?” choose “Create bridging header.” The bridging header is the place where you import Objective-C classes, and then they are visible inside Swift.

Step 2: In order to use C++ inside Objective-C, we have to change the file extension from OpenCVWrapper.m to OpenCVWrapper.mm. You can do it by simply renaming the file inside Xcode’s project navigator. Adding .mm as an extension will change the file type from Objective-C to Objective-C++.

Step 3: Import OpenCV into OpenCVWrapper.mm using the following import. It’s important to write the given import above #import "OpenCVWrapper.h" because this way we avoid a well-known BOOL conflict. OpenCV contains enum that has the value NO which causes a conflict with the Objective-C BOOL NO value. If you don’t need classes that use such enum, then this is the simplest way. Otherwise, you have to undefine BOOL before importing OpenCV.

#ifdef __cplusplus 
 
#import <opencv2/opencv.hpp> 
 
#import <opencv2/imgcodecs/ios.h> 
 
#import <opencv2/videoio/cap_ios.h> 
 
#endif

Step 4: Add #import "OpenCVWrapper.h" to your bridging header.

Open OpenCVWrapper.mm and create a private interface where we will declare private properties:

@interface OpenCVWrapper() <CvVideoCameraDelegate>
 
@property (strong, nonatomic) CvVideoCamera *videoCamera;
 
@property (assign, nonatomic) cv::Mat logoSample;
 
@end

In order to create CvVideoCamera, we have to pass UIImageView to it, and we will do that through our designator initializer.

- (instancetype)initWithParentView:(UIImageView *)parentView delegate:(id<OpenCVWrapperDelegate>)delegate {
 
   
 
    if (self = [super init]) {
 
        self.delegate = delegate;
 
       
 
        parentView.contentMode = UIViewContentModeScaleAspectFill;
 
       
 
        self.videoCamera = [[CvVideoCamera alloc] initWithParentView:parentView];
 
        self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
 
        self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetHigh;
 
        self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
 
        self.videoCamera.defaultFPS = 30;
 
        self.videoCamera.grayscaleMode = [NSNumber numberWithInt:0].boolValue;
 
        self.videoCamera.delegate = self;
 
       
 
        // Convert UIImage to Mat and store greyscale version
 
        UIImage *templateImage = [UIImage imageNamed:@"toptal"];
 
        cv::Mat templateMat;
 
        UIImageToMat(templateImage, templateMat);
 
        cv::Mat grayscaleMat;
 
        cv::cvtColor(templateMat, grayscaleMat, CV_RGB2GRAY);
 
        self.logoSample = grayscaleMat;
 
       
 
        [self.videoCamera start];
 
    }
 
    return self;
 
}

Inside it, we configure CvVideoCamera that renders video inside the given parentView and through delegate sends us cv::Mat image for analysis.

processImage: method is from CvVideoCameraDelegate protocol, and inside it, we will do template matching.

- (void)processImage:(cv::Mat&)image {
 
   
 
    cv::Mat gimg;
 
   
 
    // Convert incoming img to greyscale to match template
 
    cv::cvtColor(image, gimg, CV_BGR2GRAY);
 
   
 
    // Get matching
 
    cv::Mat res(image.rows-self.logoSample.rows+1, self.logoSample.cols-self.logoSample.cols+1, CV_32FC1);
 
    cv::matchTemplate(gimg, self.logoSample, res, CV_TM_CCOEFF_NORMED);
 
    cv::threshold(res, res, 0.5, 1., CV_THRESH_TOZERO);
 
   
 
    double minval, maxval, threshold = 0.9;
 
    cv::Point minloc, maxloc;
 
    cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);
 
   
 
    // Call delegate if match is good enough
 
    if (maxval >= threshold)
 
    {
 
        // Draw a rectangle for confirmation
 
        cv::rectangle(image, maxloc, cv::Point(maxloc.x + self.logoSample.cols, maxloc.y + self.logoSample.rows), CV_RGB(0,255,0), 2);
 
        cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(.1), cv::Scalar(1.));
 
       
 
        [self.delegate openCVWrapperDidMatchImage:self];
 
    }
 
}

First, we convert the given image to grayscale image because inside the init method we converted our Toptal logo template matching image to grayscale. Next step is to check for matches with a certain threshold which will help us with scaling and angles. We have to check for angles because you can capture a photo in various angles in which we still want to detect logo. After reaching the given threshold we will invoke delegate and open Toptal’s web page.

Don’t forget to add NSCameraUsageDescription to your Info.plist otherwise, your application will crash right after calling [self.videoCamera start];.

Now Finally Swift

So far we were focusing on Objective-C++ because all the logic is done inside it. Our Swift code will be fairly simple:

  1. Inside ViewController.swift, create UIImageView where CvVideoCamera will render content.
  2. Create an instance of OpenCVWrapper and pass the UIImageView instance to it.
  3. Implement OpenCVWrapperDelegate protocol to open Toptal’s web page when we detect the logo.
class ViewController: UIViewController {
 
   
 
    var wrapper: OpenCVWrapper!
 
   
 
    @IBOutlet var imageView: UIImageView!
 
    override func viewDidLoad() {
 
        super.viewDidLoad()
 
        // Do any additional setup after loading the view, typically from a nib.
 
   
 
        wrapper = OpenCVWrapper.init(parentView: imageView, delegate: self)
 
    }
 
}
 
extension ViewController: OpenCVWrapperDelegate {
 
    //MARK: - OpenCVWrapperDelegate
 
   
 
    func openCVWrapperDidMatchImage(_ wrapper: OpenCVWrapper) {
 
        UIApplication.shared.open(URL.init(string: "https://toptal.com")!, options: [:], completionHandler: nil)
 
    }
 
}

OpenCV Swift in Action

In this article, we have shown how you can integrate C++ code with Swift and create wrapper classes that are here for bridging C++ code with Swift. Now, when we detect the Toptal Logo through the camera, we open Toptal’s home page.

For future updates, you may want to run CV template matching in a background thread. This way, you won’t block the main thread and the UI will stay responsive. Because this is a simple example of OpenCV, template matching may not be extra successful, but the purpose of this article was to show you how you can start using it.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about OpenCV and Python

Complete Python Bootcamp: Go from zero to hero in Python 3

Machine Learning A-Z™: Hands-On Python & R In Data Science

Python and Django Full Stack Web Developer Bootcamp

Computer Vision Using OpenCV

OpenCV Python Tutorial - Computer Vision With OpenCV In Python

Python Tutorial: Image processing with Python (Using OpenCV)

A guide to Face Detection in Python

Machine Learning Tutorial - Image Processing using Python, OpenCV, Keras and TensorFlow

Face Detection using Open-CV

How to Build a Form UI with SwiftUI

How to Build a Form UI with SwiftUI

How to Build a Form UI with SwiftUI. After playing around SwiftUI for a week, I really enjoy building UI using this brand new framework. With SwiftUI, it makes UI development a breeze and allows you to write much less code.

In the introductory tutorial, we gave you an overview of SwiftUI and walked you through how to build a simple user interface. After exploring the framework for around a week, I really enjoy developing user interface with SwiftUI, even though it’s still buggy at this stage. The framework provides developers with a new way to develop a UI, allowing you to build the same UI with much less code.

The declarative syntax may be new to some developers. It’ll take some time to get used to it. But just like the time when we switched from Objective-C to Swift, you’ll enjoy writing the UI code in the declarative syntax once you manage it. You’ll feel more natural to describe the app layout you want. Together with the new instant preview feature, that lets you write code and preview the visual changes at real-time, the whole development experience is faster and more interactive.

Previously, you learned how to build a table view app and handle navigation. Today, I’d like to show you to build a simple form using SwiftUI. Below is the screen you’ll work on.

Editor’s note: The sample screen is a screen of our FoodPin app that you will learn to build in our beginner course.

Prerequisites of Using SwiftUI and Design Canvas

To follow this tutorial, you will need to have Xcode 11 installed on your Mac. Since the design canvas, that is the instant preview feature, can only work on macOS Catalina. You have to upgrade your macOS to macOS Catalina if you haven’t. At the time of this writing, both Xcode 11 and macOS Catalina (aka macOS 10.15) are currently in beta.

I also assume you have some basic knowledge of Swift. If not, you can check out this free starter guide to learn the basics.

Creating a New Project

We’ll build this screen from scratch. First, create a new project in Xcode 11 using the Single View Application template and name it FormDemo (or whatever name you like). Please make sure you enable the Use SwiftUI option.

Designing the Text Fields

We’ll begin with the implementation of the text fields and the label placing right above each of the text fields. To create a label, use the Text component and write the code like this:

Text("NAME").font(.headline)

We set the label’s value to NAME and change its font type to headline. Like UIKit, the SwiftUI framework comes with a built-in text field component. To create a text field with a placeholder, you can write the code like this:

TextField(.constant(""), placeholder: Text("Fill in the restaurant name"))

To place the label above the text field, you can use a VStack to arrange both components. Your final code should be like this:

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("NAME")
                .font(.headline)
            TextField(.constant(""), placeholder: Text("Fill in the restaurant name"))
        }
    }
}

In the design canvas, it should show you the preview of the changes in a simulator (depending on your selected model in Xcode).

If you compare the current design of the text fields with the final screen I showed you earlier, we need to make a few changes:

  • Change the background color to light gray
  • Make the text field rounded corner
  • Also, we need to add some paddings

So, update the code like this:

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("NAME")
                .font(.headline)
            TextField(.constant(""), placeholder: Text("Fill in the restaurant name"))
                .padding(.all)
                .background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0), cornerRadius: 5.0)
        }
    }
}

In the code, we updated the TextField by adding paddings for all sides (.padding(.all)) and changing its background color. We also set the corner radius to 5.0 to round the corners. Now your text field should look like this:

Both the text field and the label are too close to the left and right edges. To fix that, we can add some horizontal spaces for the vertical stack (VStack) using the padding property. So, update the code like this:

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            .
            .
            .
        }
        .padding(.horizontal, 15)
    }
}

Once changed, the text field should look better:

Extracting the Text Field for Reuse

As you can see in the final design, all text fields share the same layout and design. Instead of duplicating the code we just wrote for other text fields, it’s better to extract the code to create a separate view for reuse.

Let’s name the struct LabelTextField and move the VStack code block to this struct like this:

struct LabelTextField : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("NAME")
                .font(.headline)
            TextField(.constant(""), placeholder: Text("Fill in the restaurant name"))
                .padding(.all)
                .background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0), cornerRadius: 5.0)
        }
        .padding(.horizontal, 15)
    }
}

For reuse purpose, we’ll further modify the struct to accept two variables: label and placeholder. The LabelTextField should now look like this:

struct LabelTextField : View {
    var label: String
    var placeHolder: String
 
    var body: some View {
 
        VStack(alignment: .leading) {
            Text(label)
                .font(.headline)
            TextField(.constant(""), placeholder: Text(placeHolder))
                .padding(.all)
                .background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0), cornerRadius: 5.0)
            }
            .padding(.horizontal, 15)
    }
}

Now going back the ContentView. You can create a text field by constructing a LabelTextFieldwith the specified label name and place holder like below:

struct ContentView : View {
    var body: some View {
        LabelTextField(label: "NAME", placeHolder: "Fill in the restaurant name")
    }
}

The preview should still show you the same label design. But internally we now easily create a text field with different label and placeholder value.

Creating Multiple Text Fields Using List

The final form has multiple text fields for user input. To present multiple text fields in vertical arrangement, you can use VStack to layout the text fields. However, since we can’t display all the information in a single view, we will make the form scrollable by embedding the stack using List. In SwiftUI, it provides a container called List that allows developers to quickly build a table or present rows of data in a single column.

Now update ContentView like this:

struct ContentView : View {
    var body: some View {
        List {
            VStack(alignment: .leading) {
                LabelTextField(label: "NAME", placeHolder: "Fill in the restaurant name")
                LabelTextField(label: "TYPE", placeHolder: "Fill in the restaurant type")
                LabelTextField(label: "ADDRESS", placeHolder: "Fill in the restaurant address")
                LabelTextField(label: "PHONE", placeHolder: "Fill in the restaurant phone")
                LabelTextField(label: "DESCRIPTION", placeHolder: "Fill in the restaurant description")
                }
 
        }
 
    }
}

As soon as you make the changes, you will see the preview updated like this:

If you want to adjust the space between the left/right edge of the text field and the display, you can insert a line of code after VStack:

List {
   VStack(alignment: .leading) {
                ...
   }
   .listRowInsets(EdgeInsets())
}

By using listRowInsets, you can extend the text field closer to the edges of the display.

Adding Featured Photo

You can first download the sample photo here or use whatever photo you like. Before using the photo, import it to the asset catalog.

SwiftUI provides a component called Image for you to present an image like this:

Image("chicken")

If you’ve placed the line of code before the creation of the vertical stack (VStack), you’ll end up with a huge photo that takes up the whole screen. To scale it down, you can write the code like this:

Image("chicken")
    .resizable()
    .scaledToFill()
    .frame(height: 300)
    .clipped()

The code declares the image as a resizable view and set the content mode to Scale to fill. Also, we set the height of the frame to a fixed value. Lastly, we clip the view to its bounding frame. Your result should be like this:

To extend the photo to the edges of the display, you can call listRowInsets and set its value to EdgeInsets(). Update the Image like this:

Image("chicken")
    .resizable()
    .scaledToFill()
    .frame(height: 300)
    .clipped()
    .listRowInsets(EdgeInsets())

Now the featured photo should be perfectly displayed. Lastly, you may notice that the Name field is very close to the bottom edge of the image. Insert the following line of code after the declaration of VStack to give it some space:

.padding(.top, 20)

If you’ve followed the tutorial correctly, your screen should look like this:

Creating a Rounded Button

Now that you’ve created a simple form, let’s see how to implement the Save button. The SwiftUI framework provides a component called Button to create a button. The simplest way of constructing a button can be written like this:

Button(action: {}) {
  Text("Save")
}

Here, we define a standard button named Save. The action parameter takes in a closure, which will be triggered when the button is tapped. For this demo, the button performs nothing.

To better organize our code, we will create another struct and name it RoundedButton :

struct RoundedButton : View {
    var body: some View {
        Button(action: {}) {
            Text("Save")
        }
    }
}

But how can you preview this rounded button? You can create the RoundedButton in ContentViewto preview the design in the current simulator. Xcode 11’s Previews feature lets developers write code to add multiple previews in the design canvas. Modify the ContentView_Previews struct to generate the preview of the rounded button:

struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
            RoundedButton().previewLayout(.sizeThatFits)
        }
    }
}

The Group allows you to group multiple previews. In the code above, we still generate the preview of the ContentView in your selected simulator. For the rounded button, we call the previewLayout method to alter the preview approach. Instead of rendering the rounded button on another simulator, we set the value to .sizeThatFits. This instructs Xcode to generate the preview in a container view like below:

Now update the code of RoundedButton to the following:

struct RoundedButton : View {
    var body: some View {
        Button(action: {}) {
            HStack {
                Spacer()
                Text("Save")
                    .font(.headline)
                    .color(Color.white)
                Spacer()
            }
        }
        .padding(.vertical, 10.0)
        .background(Color.red, cornerRadius: 4.0)
        .padding(.horizontal, 50)
    }
}

We simply change the button’s font type and font color. As you can see in the final deliverable, I want to make the button to look more like a button. So, we give the button a nice background by changing its background color and adding some paddings.

To use this button and add it to the form, you can insert the following line of code in ContentViewand put it after the last text field:

RoundedButton().padding(.top, 20)

We call the padding function to add some extra space between the text field and the Save button. Now your design canvas will show something like this:

Embedding the View in a Navigation View

We’re almost done with the implementation. The final step is to embed the entire form in a navigation view. If you’ve read our introductory tutorial, you know SwiftUI provides a container view named NavigationView for creating a navigation interface. All you need to do is embed the whole list in ContentView in a NavigationView like this:

struct ContentView : View {
    var body: some View {
 
        NavigationView {
            List {
 
                Image("chicken")
                    .resizable()
                    .scaledToFill()
                    .frame(height: 300)
                    .clipped()
                    .listRowInsets(EdgeInsets())
 
                VStack(alignment: .leading) {
                    LabelTextField(label: "NAME", placeHolder: "Fill in the restaurant name")
                    LabelTextField(label: "TYPE", placeHolder: "Fill in the restaurant type")
                    LabelTextField(label: "ADDRESS", placeHolder: "Fill in the restaurant address")
                    LabelTextField(label: "PHONE", placeHolder: "Fill in the restaurant phone")
                    LabelTextField(label: "DESCRIPTION", placeHolder: "Fill in the restaurant description")
 
                    RoundedButton().padding(.top, 20)
                }
                .padding(.top, 20)
                .listRowInsets(EdgeInsets())
            }
 
            .navigationBarTitle(Text("New Restaurant"))
            .navigationBarItems(trailing:
                    Button(action: {
 
                    }, label: {
                        Text("Cancel")
                    })
            )
        }
 
    }
}

To configure the title of the navigation bar, we call the navigationTitle function and specify the text component. If you need to set the bar items, you can call the navigationBarItems function to configure the view appeared on the leading/trailing edge of the navigation bar. In the code above, we configure the trailing edge with a Cancel button.

Previewing the UI with Fixed Layout

That’s how you lay out a form using SwiftUI. One last thing I want to show is the power of Xcode Previews. As you can see, the form is too long for the screen. To view the entire form, you can hit the Play button to run the app and then you can scroll through the form. Xcode 11 offers an alternative way to preview the entire form. Edit the ContentView_Previews struct and initiate the ContentView like this:

ContentView().previewLayout(.fixed(width: 375, height: 1000))

Instead of previewing the layout on a simulated device, we tell Xcode to render the preview in a fixed rectangular frame. By doing that, you can preview the entire form without running the app.

What’s Next

After playing around SwiftUI for a week, I really enjoy building UI using this brand new framework. With SwiftUI, it makes UI development a breeze and allows you to write much less code. I’m still exploring the framework, so please let me know if you find any errors in the tutorial.

In the future tutorials, we will cover other features of SwiftUI such as animations and complex layouts. Please stay tuned and let me know if you have any feedback. Love to read your comment.

Further reading:

How To Code A Dynamic Header In Flutter

Top 5 animations libraries you can use in React Native

How to build a simple CRUD with GraphQL and Flutter

A Deep Dive into Flutter: Front-end Frameworks for Developers

Flutter Tutorial: Flutter Layout Cheat Sheet

Dart Programming Tutorial - Full Course

Build a CRUD app using Firebase and Flutter (Provider)