Search code examples
iosswiftuiviewios8uiresponder

How do I redeclare a property as read-write in UIResponder subclass with swift?


I'm trying to follow this guide, but using swift: InputAccessoryView docked at bottom

I can't seem to set the inputAccessoryView for my ViewController, according to the documentation, I need to redeclare it:

The value of this read-only property is nil. If you want to attach custom controls to a system-supplied input view (such as the system keyboard) or to a custom input view (one you provide in the inputView property), redeclare this property as read-write in a UIResponder subclass. You can then use this property to manage a custom accessory view. When the receiver becomes the first responder, the responder infrastructure attaches the accessory view to the appropriate input view before displaying it.

I can't figure out how to do this using swift. Any help is greatly appreciated.


Solution

  • Old question but this may be of use to those not overly familiar with Objective-C.

    I'm not sure how to achieve this with swift alone but it's easy enough to do the "dirty work" in objective c land and utilise the result in swift

    Process

    This approach requires 3 files to be added to your project.

    1. Add an objective C class, copy and paste the following code into the two new files (.h, .m)
    2. Add a bridging header and copy and paste into it the specified import
    3. At this point you can extend any swift class from this Objective c class instead of UIView and et voila, you can change the inputAccessoryView.

    Enjoy

    .h file

    #import <UIKit/UIKit.h>
    
    /**
     * Starting point for subclasses that allow input accessorty view to be changed
     */
    @interface YourBaseView : UIView
    
    @property (readwrite,nonatomic) UIView*_Nullable inputAccessoryView;
    @end
    

    .m file

    #import "YourBaseView.h"
    
    @implementation YourBaseView
    
    /*
     // Only override drawRect: if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     - (void)drawRect:(CGRect)rect {
     // Drawing code
     }
     */
    
    @end
    

    Bridging Header

    In the "YOUR_PROJECT_NAME-Bridging-Header.h" (or whatever its called in the Objective-C Bridging Header property in build settings of your project (SWIFT_OBJC_BRIDGING_HEADER)

    #import "YourBaseView.h"
    

    Swift Demo

    class YourSwiftAccessoryInputView : YourBaseView
    {
        //the rest is up to you
    }
    
    let instance = YourSwiftAccessoryInputView(frame: CGRect(x:0, y:0,width:100,height:100))
    instance.inputAccessoryView = Some view