2

As a relative noob to iOS development I'm struggling to make a PHFComposeBarView control become active in my Swift iOS app.

Having squinted at the Obj-C in the PHFComposeBarView example app and this SO answer, I've managed as best I can to translate the basic setup into Swift such that the control is displayed in the main view:

enter image description here

However, I haven't managed to make the control become active programatically.

I've created a minimal test case project in Swift 2.0/XCode 7.0 Beta 2 whose ViewController looks like:

ViewController.swift:

import UIKit
import PHFComposeBarView

class ViewController: UIViewController, PHFComposeBarViewDelegate {

    var composeBar: PHFComposeBarView {
        let viewBounds = self.view.bounds
        let frame = CGRectMake(0.0, viewBounds.size.height - PHFComposeBarViewInitialHeight, viewBounds.size.width, PHFComposeBarViewInitialHeight)
        let composeBarView = PHFComposeBarView(frame: frame)
        composeBarView.delegate = self
        return composeBarView
    }

    override var inputAccessoryView: UIView {
        return self.composeBar
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override func viewDidAppear(animated: Bool) {
        print("viewDidAppear self \(self)")
        print("composeBar.delegate \(self.composeBar.delegate)")
        print("composeBar.textView.delegate \(self.composeBar.textView.delegate)")
        print("composeBar.canBecomeFirstResponder() \(self.composeBar.canBecomeFirstResponder())")
        print("composeBar.textView.canBecomeFirstResponder() \(self.composeBar.textView.canBecomeFirstResponder())")
        let res = self.composeBar.becomeFirstResponder()
        print("composeBar.becomeFirstResponder() \(res)")
        print("composeBar.isFirstResponder() \(self.composeBar.isFirstResponder())")
        print("composeBar.textView.isFirstResponder() \(self.composeBar.textView.isFirstResponder())")
    }

}

Console:

viewDidAppear self <SwiftPHFComposeBarTest.ViewController: 0x7fe088619d90>
composeBar.delegate Optional(<SwiftPHFComposeBarTest.ViewController: 0x7fe088619d90>)
composeBar.textView.delegate Optional(<PHFDelegateChain: 0x7fe088654850>)
composeBar.canBecomeFirstResponder() true
composeBar.textView.canBecomeFirstResponder() true
composeBar.becomeFirstResponder() false
composeBar.isFirstResponder() false
composeBar.textView.isFirstResponder() false

How can it be that composeBar.canBecomeFirstResponder() returns true but composeBar.becomeFirstResponder() returns false?

Also, I'm not sure if the delegate being an Optional is a problem.

EDIT: Updated to include debug output.

Community
  • 1
  • 1
fractious
  • 1,642
  • 16
  • 30
  • A quick search for "input accessoryview becomefirstresponder" returned this: http://stackoverflow.com/questions/19983179/uitextfield-in-inputaccessoryview-wont-becomefirstresponder – fphilipe Jul 06 '15 at 13:25
  • 1
    Thanks Philipe. Sadly, adding a `self.view.window!.makeKeyAndVisible()` to the end of my `viewDidAppear()` method makes no difference. I have however noticed that I'm getting different behaviour in iOS 9 beta and iOS 8.3, in that tapping the control does display the keyboard as expected in 8.3 but then crashes with an `EXC_BAD_ACCESS` exception when attempting to type a character. I'll see if I can narrow this down to an iOS version issue. – fractious Jul 06 '15 at 14:12
  • Hmmm, that doesn't seem to be it, the PHFComposeBarView example app works fine in 8.3 and 9.0 beta. – fractious Jul 06 '15 at 14:21
  • Sorry, not sure what it could be. Try using a simple text view instead and see if that works and trouble shoot from there. Good luck! – fphilipe Jul 06 '15 at 14:37
  • N.B. Post updated to include debug output. – fractious Jul 07 '15 at 11:55

1 Answers1

1

Well, one solution appears to be to use the storyboard instead:

ViewController.swift:

import UIKit
import PHFComposeBarView

class ViewController: UIViewController, PHFComposeBarViewDelegate {

    @IBOutlet weak var composeBarView: PHFComposeBarView!

    override func viewDidLoad() {
        super.viewDidLoad()
        composeBarView.delegate = self
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override var inputAccessoryView: UIView {
        composeBarView.removeFromSuperview()
        return composeBarView
    }

}

Screenshot

fractious
  • 1,642
  • 16
  • 30
  • have you checked tapping 2 times inside the textview once it is open..?? It'll disappear .. – Akshay Oct 27 '15 at 08:48