grethi / CHGInputAccessoryView

MIT License
7 stars 1 forks source link

Xcode 9 swift 3 Compatibility #2

Open mn288 opened 7 years ago

mn288 commented 7 years ago

Hello, ever since I updated to Xcode 9, this library hasn't displayed properly since Will there be an update soon?

grethi commented 7 years ago

I have not yet tested the Pod with Xcode 9 but will do so as soon as possible. As it is a Objective-C only Pod i do not expect any problems when using swift simultaneously.

May you explain the problems you mentoined a bit more in detail?

mn288 commented 7 years ago

The problem was that after adding an item, the toolbar would not add the right constratints. I fixed the problem but after invoking a Layoutsubview for the accessory view. Thank you for your great effort with this library.

mn288 commented 7 years ago

I apologize, still facing problems with the library. After "layoutSubviews" invocation, anytime the accessoryView resigns or becomes first responder, the toolbar resizes and trims off the "title" or "image" item in the toolbar

grethi commented 7 years ago

After spending some time finding the issue i could not yet find a solution.

The problem i am facing is that items with flexible width (i.e. TextView or TexFiled) will not place correctly at the first insert but the width seems to be calculated as expected.

What items do you add to the accessoryView? I assume items with flexible size?

mn288 commented 7 years ago

I am using the custom initializer below (I am using swift 3.0 on Xcode9) I managed to solve it by add a tag to the button and adding a fixed width in the sub layout

extension CHGInputAccessoryView{

    class func inputAccessoryViewTextView(withButtonImage image: UIImage, textViewDelegate delegate: UITextViewDelegate?) -> CHGInputAccessoryView {
        let accessoryView = CHGInputAccessoryView.init(height: 45)
        if let textViewItem = CHGInputAccessoryViewItemTextView.item(with: delegate){
            textViewItem.textView.returnKeyType = .default
            textViewItem.flexibleSize = true
            let button = CHGInputAccessoryViewItem.button(with: image.overlayImage(color: UIColor.carpoloYellow()))
            button?.flexibleSize = false
//added this tag to the custom button
            button?.tag = 1989
            accessoryView?.setItems([textViewItem, button!], animated: true)
            accessoryView?.item(at: 1).tintColor = UIColor.carpoloYellow()
            accessoryView?.updateHeightConstraint()
            accessoryView?.layoutSubviews()
        }
        return accessoryView!
    }
}

I fiddled with the layoutSubviews function in CHGInputAccessoryView.m file as follows


- (void)layoutSubviews
{
    [super layoutSubviews];

    NSMutableArray *flexibleSizeItems = [[NSMutableArray alloc] init];
    CGFloat itemWidth = 0.f;
    CGFloat itemMargin = _itemMargin * 2;
    for (UIBarButtonItem *item in self.items) {
        if ([item isKindOfClass:[CHGInputAccessoryViewItem class]]) {
            if (((CHGInputAccessoryViewItem *)item).flexibleSize) {
                [flexibleSizeItems addObject:item];
            } else {
                UIView *itemView = [item valueForKey:@"view"];
                itemWidth = CGRectGetWidth(itemView.frame) + itemMargin;
            }

           // added a fixed width to the tagged item (**in this case its a button**)
            if (item.tag == 1989){
                itemWidth = 60;
                 UIView *itemView = [item valueForKey:@"view"];
                itemView.frame = CGRectMake(itemView.frame.origin.x, itemView.frame.origin.y, 60, 60);
            }
        }
    }

    if (flexibleSizeItems.count > 0) {
        CGFloat flexItemWidth = (CGRectGetWidth(self.frame) - itemWidth) / flexibleSizeItems.count - itemMargin;

        for (CHGInputAccessoryViewItem *item in flexibleSizeItems) {
            CGRect frame = item.customView.frame;
            frame.size.width = flexItemWidth;
            item.customView.frame = frame;
            [item resizeToHeight:(CGRectGetHeight(self.bounds) - itemMargin)];
        }
    }
}
grethi commented 7 years ago

Hi @mn288, thanks for your contribution. This helped to figure out the real bug.

After adding some logs i found out that all UIBarButtonItems with title are providing wrong width information. But this width is necessary to calculate the width for all flexible width items like textfields and textviews. The reason seems to be the new auto-layout behavior in iOS 11 for all bars as mentioned in the WWDC2017 session 204. Currently, i do not know how to add a flexible width item to a toolbar and defining the correct constraints to fit inside the superview and next to all the other items.

Any ideas?

Your solution works because you are defining a fixed width for the button which is necessary to calculate the flex item size.

mn288 commented 7 years ago

hi @grethi,

I sure hope I am helping out.

Give the library a function to set the size of each control on the UIBarButtonItem, or give it a default size that can be overridden for each item. Also, you can add an auto layout generator for the items based on trailing and leading (just give me a couple of days and I will send you the generator) that will enable the items to automatically have the needed constraints to be flexible automatically) In my solution I gave it a fixed size because it is only needed at that width throughout several other view.

**This is based on the new auto layout recommendation in the video (You also sent) starting the 9th minute to the 10th minute.

grethi commented 7 years ago

Hi @mn288,

using a fixed or default size for each item is not an option. I decided to use the UIToolbar because you do not have to deal with sizes or positions as the toolbar will handle it for you.

I tried using NSLayoutConstraints to place the UIBarButtonItems but with no success. You may check the StackOverflow Question and help getting it solved.

Cheers.

Btw.: I found a similar POD wich will offer some nice input bars. They also used a UIToolbar before iOS 11 but now moved to a simple UIView with a complete set of layout constraints.