Swift 28
Tutorial: Play Video in Swift
Recently I needed to add a video as a background in one of my apps. This is a really nice effect if it’s a looping video. On top of the video I had some other elements and buttons, it was cool to see motion happening behind. The code snippet below displays the video full screen with no controls and it repeats, but you could change the properties to suit your needs.
- First add the video to your project, just like any file, you can drag it into your Project Navigator or right click in the Project Navigator and select “Add Files”. Be sure to choose the targets that you need to add the file to, if you have more than one.
- In the Project Navigator select your Project Root > Your Target > Build Phases > Copy Bundle Resources. Check to see that you video is there, if not click the plus sign to add it.
- Add this import statement to the top of your View Controller.
import MediaPlayer
- Add this property to your class.
var moviePlayer : MPMoviePlayerController!
- Add the code below to create and play your video. This can be added to your ViewDidLoad() method or create your own function.
let path = NSBundle.mainBundle().pathForResource("Video", ofType:"mp4") let url = NSURL.fileURLWithPath(path!) self.moviePlayer = MPMoviePlayerController(contentURL: url) if let player = self.moviePlayer { player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height) player.view.sizeToFit() player.scalingMode = MPMovieScalingMode.Fill player.fullscreen = true player.controlStyle = MPMovieControlStyle.None player.movieSourceType = MPMovieSourceType.File player.repeatMode = MPMovieRepeatMode.One player.play() self.view.addSubview(player.view) }
Tutorial: Share on Twitter and Facebook in Swift
Apple has integrated Twitter login support since iOS 5, and Facebook since iOS 6. In the past, developers had to integrate the full Facebook and Twitter SDK to integrate sharing in their apps. Since it’s built in, it’s much easier to add these social features to your own app.
Note: If you would like to learn how to share with the native Facebook SDK, read this article: Tutorial: How To Share in Facebook SDK 4.0 for Swift
Using the Social Framework allows applications to interact with social networks from a single API without having to manage authentication. Users login to Facebook and Twitter at the OS level within the “Settings” app, so you don’t need to integrate the full Facebook or Twitter SDK and handle login yourself, it’s already done for you. It includes a system provided view controller for composing posts as well as an abstraction that allows consuming each social network’s API over HTTP.
The Social framework comes with a class named SLComposeViewController. The SLComposeViewController class presents a standard view controller for users to compose a tweet or Facebook post. It also allows developers to preset the initial text, attach images and add URL to the post. If you just want to implement simple sharing feature, this is the only class you need to know.
Below is what the SLComposeViewController looks like in your app.
For both, you’ll need to import the Social Framework.
import Social
Share on Twitter
- Go to the Storyboard and design the user interface. In the view, add the Facebook button.
- Create an action method below and name it as “twitterButtonPushed”. This method will be invoked when the button detects a Touch Up Inside event.
@IBAction func twitterButtonPushed(sender: UIButton) { if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){ var twitterSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter) twitterSheet.setInitialText("Share on Twitter") self.presentViewController(twitterSheet, animated: true, completion: nil) } else { var alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to share.", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } }
- In the Storybaord, right click the Twitter button or switch to the Connections inspector in the right pane. Next drag a connection between “Touch Up Inside” and the View Controller on the left where the “twitterButtonPushed” method is defined.
- Test it out, run your app and when you press the Facebook button you should see the SLComposeViewController popup so the user can enter their text to share on their Twitter stream. Be sure to set the initial text value to whatever you like.
Share on Facebook
- Go to the Storyboard and design the user interface. In the view, add the Facebook button.
- Create an action method below and name it as “facebookButtonPushed”. This method will be invoked when the button detects a Touch Up Inside event.
@IBAction func facebookButtonPushed(sender: UIButton) { if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook){ var facebookSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook) facebookSheet.setInitialText("Share on Facebook") self.presentViewController(facebookSheet, animated: true, completion: nil) } else { var alert = UIAlertController(title: "Accounts", message: "Please login to a Facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } }
- In the Storybaord, right click the Facebook button or switch to the Connections inspector in the right pane. Next drag a connection between “Touch Up Inside” and the View Controller on the left where the “facebookButtonPushed” method is defined.
- Test it out, run your app and when you press the Facebook button you should see the SLComposeViewController popup so the user can enter their text to share on their Facebook page. Be sure to set the initial text value to whatever you like.
You can grab the full source code for this tutorial. Note: Built using Xcode 6.1.
Tutorial: Today Widget in Swift
App extensions in the Today view are called widgets. Widgets give users quick access to information that’s important right now. For example, users open the Today view to check current stock prices or weather conditions, see today’s schedule, or perform a quick task such as marking an item as done. Users tend to open the Today view frequently, and they expect the information they’re interested in to be instantly available.
The best widgets give users quick updates or enable very simple tasks. If you want to create an app extension that enables a multistep task or helps users perform a lengthy task, such as uploading or downloading content, the Today extension point is not the right choice.
Because user interaction with Today widgets is quick and limited, you should design a simple, streamlined UI that highlights the information users are interested in. In general, it’s a good idea to limit the number of interactive items in a widget. In particular, note that iOS widgets don’t support keyboard entry.
Below is a tutorial that implements a Time Widget to display clocks for a couple of time zones. This fits into the Apple requirement of making it a simple dynamic task that users may need frequently without wanting to open a full app.
Setup the Application Extension
- Select File > New > Project. Select the Single view application template, and call it TodayWidget.
- Add the Application Extension Target. Select File > New > Target…. Then in the left pane, select Application extension and under that choose Today Extension. Because our Today extension is going to show times, give it the name TimeWidget.
- A message will popup asking if you want to activate the “TimeWidget” scheme. Click Cancel. We will debug it using the normal Application scheme.
Create the Today Widget View
Today widgets are just like any other view within your application and built using a UIViewController. Next we’ll create our view for what will appear in the widget.
- In the project navigator, expand TimeWidget group and click on MainInterface.storyboard.
- Select the “Hello World” label already there and delete it.
- Click on the “View” and open the Size Inspector and change the height of the view to 60.
- Drag a eight UILabels into the view, the top four be the titles of the time zones and the bottom four will be clocks. See the image below.
- Define your IBOutlet label variables within the “TodayViewController.swift” and add in the perferredContentSize of the view so it will display the correct height in the Today View.
// // TodayViewController.swift // TimeWidget // // Created by Brian Coleman on 2014-10-16. // Copyright (c) 2014 Brian Coleman. All rights reserved. // import UIKit import NotificationCenter class TodayViewController: UIViewController, NCWidgetProviding { @IBOutlet var pacificLabel: UILabel! @IBOutlet var mountainLabel: UILabel! @IBOutlet var centralLabel: UILabel! @IBOutlet var easternLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view from its nib. self.preferredContentSize = CGSizeMake(320, 50); } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResult.Failed // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData completionHandler(NCUpdateResult.NewData) } }
- Connect the IBOutlets to the new variables within the MainInterface.storyboard.
Test Your Today Widget
- When you run the app you’ll see a blank view since our app doesn’t do anything except create the Today Widget.
- Drag from the top of your view down to display the notification center. Next tap the “Edit” button.
- Tap the green plus button next to the TimeWidget. You’ll see it got added below the Calendar. Drag it to re-order it so it shows above the Calendar.
- Tap “Done” and you should see our TimeWidget displayed in the Today Widget view.
Add in Live Dynamic Data
We are almost done making our widget, let’s add in the clocks to finish it up.
import UIKit import NotificationCenter class TodayViewController: UIViewController, NCWidgetProviding { @IBOutlet var pacificLabel: UILabel! @IBOutlet var mountainLabel: UILabel! @IBOutlet var centralLabel: UILabel! @IBOutlet var easternLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view from its nib. self.preferredContentSize = CGSizeMake(320, 50); self.updateClocks() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResult.Failed // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData completionHandler(NCUpdateResult.NewData) } func updateClocks() { var time: NSDate = NSDate() println("Time: \(time)") var timeString : NSString = "Time: \(time)" let formatter:NSDateFormatter = NSDateFormatter(); var timeZone = NSTimeZone(name: "UTC") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("UTC Time: \(formatter.stringFromDate(time))") timeZone = NSTimeZone(name: "US/Eastern") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("EST Time: \(formatter.stringFromDate(time))") easternLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Pacific") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("PST Time: \(formatter.stringFromDate(time))") pacificLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Mountain") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" println("MT Time: \(formatter.stringFromDate(time))") mountainLabel.text = formatter.stringFromDate(time) timeZone = NSTimeZone(name: "US/Central") formatter.timeZone = timeZone formatter.dateFormat = "HH:mm" centralLabel.text = formatter.stringFromDate(time) } }
You can grab the full source code for this tutorial. Note: Built for Xcode 6.0.
Tutorial: How to use Auto Layout in Xcode 6
Apple just introduced the new iPhone 6 (4.7in) and iPhone 6 Plus (5.5in). These are two additional sizes to the existing iPhone 4 (3.5in), iPhone 5 (4in), and iPad (9.4in). As iOS developers we have long enjoyed not having to develop for too many different screen sizes, unlike Android, until now. With this many screens available, your apps need to be flexible enough to work on all of them or Apple may reject it or even worse, users will complain it doesn’t work for them on their device.
Below is a simple tutorial to help you with adding constraints to your views using Storyboards, without having to write any code. This is helpful for handling auto rotation as well.
Designing an Interface using Constraints
- Make a new project based on the Single View Application template, and name it AutoLayout.
- Select Storyboard to edit the interface. One nice thing about using constraints is that they accomplish quite a lot using no code. All of the auto layout implementation can be done right here in the Storyboard.
- Add four labeled buttons. Drag four round rect buttons from the library over to your view. Use the dashed blue guidelines to help you line up each one near its respective corner. Double-click each button, and assign a title to each one so you can tell them apart later.
- Run It. Let’s see what happens now that we’ve specified that we support autorotation but haven’t set any autosize attributes. Build and run the app. Select Hardware Rotate Left, which will simulate turning the iPhone to landscape mode. Notice that all of the buttons except for the top left one is off the screen. We need to fix this.
- The image below shows an example of the Auto Layout Menu. You’ll find this in the bottom right of the Storyboard. First select which view you want to modify, then choose one of the buttons to modify it’s layout properties.
Align – Create alignment constraints, such as aligning the left edges of two views.
Pin – Create spacing constraints, such as defining the width of a UI control.
Issues – Resolve layout issues.
Resizing – Specify how resizing affects constraints.© Copyright 2014 AppCoda
- Let’s add our constraints. Click the upper-left button to select it. Choose the Pin button to change constraints for the button. Add 20px to the top and 0px to the left. Then press the “Add 2 Contraints” button to make the change.
- You’ll see that the constraints are now set by the blue lines now displayed when the button is selected. You may not see blue lines for the top left button since all constraints for that location are by default.
- Now do the same for the other three buttons.
- Run it and look at the results. Each button stuck tight to its nearest corner. The buttons on the right shifted out to the right to match the view’s new width, and the buttons on the bottom were pulled up to match the new height.
You can grab the full source code for this tutorial. Note: Built for XCode6-Beta7.
Additional Tips for using Auto Layout
Use Auto Layout to lay out your views relative to each other without fixed origins, widths, and heights, so that views reposition and resize appropriately when the language or locale changes. Auto Layout makes it possible to have one set of .storyboard and .xib files for all devices.
Remove fixed width constraints. Allow views that display text to resize. If you use fixed width constraints, text may appear cropped in some views.
Use intrinsic content sizes. The default behavior for text fields and labels is to resize automatically. If a view is not adjusting to the size of text, select the view and choose Editor > Size To Fit Content.
Use leading and trailing attributes. When adding constraints, use the attributes leading and trailing for horizontal constraints. The attributes leading and trailing are equivalent to left and right. The leading and trailing attributes are the default values for horizontal constraints.
Pin views to adjacent views. Pinning causes a domino effect. When one view resizes to fit text, other views do the same. Otherwise, views may overlap in some devices.
Constantly test your layout changes. Test your app using different device sizes, like iPhone 4, iPhone 5, iPhone 6, iPhone 6 Plus, and iPad.
Don’t set the minimum size or maximum size of a window. Let the window and its content view adjust to the size of the containing views.
Auto Layout is enabled by default when you create a new project. To enable Auto Layout for an older project, select the first view of the View Controller, then select the File Inspector (first one on the left) and make sure the “Use Auto Layout” check mark is selected.
Tutorial: Collection View using Swift
One of the best features for developers that came in the iOS 6 SDK is UICollectionView. It’s been a popular tool for developers since, so let’s review how to create one in Swift (if you need it in objective-c read Tutorial: Collection View using Flow Layout).
UICollectionView is very similar to UITableView but you can customize it a lot more and it can scroll horizontal, goodbye scroll views! Most recently I used a collection view for a bottom navigation scroller and it worked really well.
A UICollectionView view has three main components:
1. Cells: Display your content in cells that are de-queued as they leave the screen.
2. Supplementary Views: Add labels, section headers and footers to define your content areas.
3. Decoration Views: Decorate the collection view to look like a bookshelf or a background image.
Start by adding the delegates to your class file and define your collection view.
class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView?
The most common layout for a UICollectionView is UICollectionViewFlowLayout. Flow layout organizes items into a grid with optional header and footer views for each section. The items in the collection view flow from one row or column (depending on the scrolling direction) to the next, with each row comprising as many cells as will fit. Cells can be the same sizes or different sizes.
Define the UICollectionView & UICollectionViewFlowLayout properties in the viewDidLoad method.
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) layout.itemSize = CGSize(width: 90, height: 90) collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) collectionView!.dataSource = self collectionView!.delegate = self collectionView!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell") collectionView!.backgroundColor = UIColor.whiteColor() self.view.addSubview(collectionView!) }
Most of the properties are self explanatory but the key is to define your cell class if you are using custom cells (just like table views) and setting the size of the cells, above they are set to 90×90. Choose your section insets which is the spacing in between each cell, I have it set to 20 for the top and 10 for the rest. Lastly define the layout, we’re using let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout().
Setting up a UICollectionView is very similar to a UITableView, so you’ll recognized a lot of the methods below.
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 1 } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 20 }
Above we’re defining how many items and sections are in the collection view. If you have more than one section, then you’ll need to define the number of sections, if you only have one you don’t need that method.
Below is the real meat of the UICollectionView, defining the cells with your data. If you choose to use a custom cell you can add images or whatever you need to display.
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as CollectionViewCell cell.backgroundColor = UIColor.blackColor() cell.textLabel?.text = "\(indexPath.section):\(indexPath.row)" cell.imageView?.image = UIImage(named: "circle") return cell }
Finally you can drag the UICollectionView object into your view within your NIB or storyboard. Move and scale the collection view to where you want to display it and review all of the properties within the inspector. Be sure to hookup the collectionView reference outlet and dataSource and delegates so the collection view can provide all the functionality available. Do the same for the Collection View Flow Layout. (See image on the right).
You can grab the full source code for this tutorial. Note: Built for XCode6-Beta7.
If you need it built using Xcode 6.3 (Swift 1.2).