Implementing the custom compact view

To start implementing the Messages extension for The Daily Quote, a new extension should be added to the project. Pick the Messages extension and name it The Daily Quote Messages. Enable the App Groups capability for this extension and include Quotes.swift in the extension target, just like you've done before.

You will use the same view-controller containment technique you used when building the custom sticker pack. This time you will add the view controller that should be displayed to the extension's Storyboard without connecting it to MessagesViewController. Before you do this and create the interface, you should implement the code for the compact view. The compact view will feature a quote, the creator of the quote, and a Share button.

Create a new UIViewController subclass and name it CompactViewController. Make sure to add it to the correct target by selecting the extension's folder before creating the new file. The setup for this view controller will be really similar to all of the other view controllers you've created for The Daily Quote and its extensions. The view will contain two outlets, one for the quote and one for its creator. In viewDidLoad(), the current quote should be fetched and the labels should be populated with the correct values. I trust you to be able to do this on your own. When in doubt, check the other projects. Alternatively, check the source code in the code bundle for this chapter.

When a user taps the Share button, the current quote should be shared as a message in the active conversation. This means that MessagesViewController will have to be aware of the share command that occurs in CompactViewController. To do this, you can create a QuoteSelectionDelegate protocol to which MessagesViewController can conform.

The delegate and the share action should be implemented in CompactViewController, as shown in the following code snippet:

var delegate: QuoteSelectionDelegate? 

@IBAction func shareTapped() {  
  delegate?.shareQuote(Quote.current)  
}

The delegate is optional because it can't be set before the view controller is initialized. The tap action simply calls a method on the delegate and passes the current quote along with it. Create a new file to define the protocol and name it QuoteSelectionDelegate. The protocol should be implemented as follows:

protocol QuoteSelectionDelegate {  
  func shareQuote(_ quote: Quote)  
}

This is a simple protocol with just a single method requirement. Now, let's write all the required code in MessagesViewController before implementing the interface for CompactViewController. First of all, add the property shown in the following snippet to the message view controller so it can hold on to the compact view controller. Also, update your viewDidLoad implementation as follows:

var compactViewController: CompactViewController?  

override func viewDidLoad() {
  super.viewDidLoad()

  compactViewController = storyboard?.instantiateViewController(withIdentifier: "CompactViewController") as? CompactViewController
  compactViewController?.delegate = self
}

The instantiateViewController(withIdentifier:) method from UIStoryboard is used to obtain an instance of CompactViewController from the storyboard.

Add an extension to MessagesViewController so it conforms to QuoteSelectionDelegate. Add an empty implementation for shareQuote(_:) to the extension. You will implement the share functionality later.

Because the user can switch between the compact and expanded state as they please, it's a good idea to abstract the code to show the compact and expanded views into their own methods. Doing this will make your code easier to read, and it avoids code duplication. Add the following method to MessagesViewController to show the compact view controller:

func showCompactView() {
  guard let compactViewController = self.compactViewController
    else { return }

  compactViewController.willMove(toParent: self)
  addChild(compactViewController)
  compactViewController.didMove(toParent: self)

  view.addSubview(compactViewController.view)
  compactViewController.view.frame = view.frame
}

This code is very similar to what you saw when you implemented the sticker pack. The last step to show the compact view is to implement willBecomeActive(with:). showCompactView() will be called from this method as follows:

override func willBecomeActive(with conversation: MSConversation) {
  if self.presentationStyle == .compact {
    showCompactView()
  }
}

Now, open MainInterface.storyboard and drag out a view controller. Add two labels and a button to this view controller. Lay them out as shown as shown in the following screenshot:

The quote is styled as a title and its maximum number of lines is set to 0 lines, so it automatically expands to fit the content. The creator is styled as caption one, and it's positioned below the title. The button should be laid out below the caption. Make sure to set CompactViewController as both the subclass and the storyboard ID for the view controller you just added. To wrap it up, connect the outlets to the views. Make sure to select Touch up inside as the trigger action for shareTapped().

If you build and run your application now, the quote for today should pop up right inside iMessage:

This is all you need to do to implement the compact view. Now let's implement an expanded view for the iMessage app.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.214.37