Category Archives: iOS

Simulated Metrics for View Controllers

I had a trouble with navigation controllers. Child view controllers were programmatically pushed, and I did not know how to get customized navigation bars. I first attached navigation controllers to those child view controllers and it seemed to work. Then, I got warning messages saying that the navigation controllers was not unreachable. It is only warnings but I decided to dig about what I do not know.

The first thing I tried was to delete those navigation controllers from the storyboard. Surprisingly, it still worked as expected. The items on the customized navigation bars were still there. In fact, they belonged to view controllers, not navigation controllers. According to Apple, it should be possible to have customized navigation bars. Usually, something that can be programmatically set may be done with the interface builder. Then, I found that Simulated Metrics in the Attribute Inspector allows one to show and hide navigation bars in the interface builder. After some tries, I ended up the setting Translucent Navigation Bar for the Top Bar entry of the Simulated Metrics.

Screen Shot 2018-03-04 at 8.37.06 PM.png
Advertisements

Presenting view controllers

I am building an app using a tab bar view controller. What happens is as follows.

  1. I presented a view controller modally over a current context. I used present(_:animated:completion:) with the property modalPresentationStyle set to currentContext
  2. I selected a different tab bar item.
  3. I came back to the original tab bar item. So I saw the view controller presented in Step 1.
  4. I dismissed the view controller and got a black screen.

It seems that the instance method present(_:animated:completion:) is dedicated to the case wherein the user comes back directly to the presenting view controller. So I guess I am supposed to disable any options that send a user to a different scene.

Another resolution would be using a navigation controller. I wondered whether I need to put additional navigation controllers to build a stack of view controllers, but it was not the case. I just need to use the method pushViewController(_:animated:) of an instance of UINavigationController. So I only need one navigation controller. Once I used pushViewController(_:animated:), I can dismiss the view controller by popping or popViewController(animated:). In fact, there are two other options: popToRootViewController(animated:) and popToViewController(_:animated:).

The following page is very helpful here: Pushing, Popping, Presenting, & Dismissing ViewControllers

I also checked Wikepedia. It says:
Users must interact with the modal window before they can return the parent application.

Referencing a textField inside a tableViewCell

I needed to know which textField within a tableViewCell was updated. In the NMR Calculator app, I kept the references of textFields. Now, I have realized that it is not a good way. So I started searching a solution.

First, I found that it is possible to get an indexPath from the point or frame of something. Then, I found this page from Stack Overflow: Get indexPath of UITextField in UITableViewCell with Swift

With a textField, finding the indexPath of the tableViewCell owning the textField can be done this way. First, the tableViewCell is set to be a delegate of the textField, when the method tableView(_:cellForRowAt:) is called. Second, a protocol for the tableViewCell is defined.

protocol SomeTableViewCellDelegate: AnyObject {
  func didEndEditing(_ cell: SomeTableViewCell)
}

class SomeTableViewCell: UITableViewCell {
  @IBOutlet weak var textField: UITextField!

  weak var delegate: SomeTableViewCellDelegate?

  override func awakeFromNib() {
    super.awakeFromNib()
    textField.delegate = self
  }
}

Now the viewController owning the tableView is set to be a delegate of SomeTableViewCell and conforms to the protocol SomeTableViewCellDelegate.

extension SomeViewController: SomeTableViewCellDelegate {
  func didEndEditing(_ cell: SomeTableViewCell) {
     let indexPath = tableView.indexPath(for: cell)
  }
}

A delegation of a delegation! I would like to adapt this elegant design pattern in the NMR Calculator app.

Passing Data Between View Controllers in iOS

Passing Data Between View Controllers in iOS: the Definitive Guide (Best Practices + Examples)

http://matteomanferdini.com/how-ios-view-controllers-communicate-with-each-other/

I want to pass some information from a child (or destination) view controller to a parent (or source) view controller. The above webpage explains very well how to do the job.

As quoted in the above webpage,

Always use a delegate to communicate information back to other controllers. Your content view controller should never need to know the class of the source view controller or any controllers it doesn’t create.

So I must not create any references of a parent view controller in a child view controller.