How to prevent a UIScrollView from cutting off a button?

Viewed 69

I'm wondering about options for preventing a scroll view from cutting off a button/view on the border of a page. My app has a text view that acts as a text editor. It has an input accessory view for the keyboard that contains about 20 different toolbar formatting buttons for the user to apply to the text. Because there are so many buttons, the toolbar accessory view is in a scroll view that scrolls horizontally.

My issue is, on some screens (depending on the device screen size) a button might be cut off at the edge of the view. When swiping to go to the next page (it uses paging), the button is still cut off on the opposite side of the screen. I will attach two screenshots that show the Underline button being cut off before and after a page swipe.

Notice the "U" button on the far right:

enter image description here

After a page swipe, the 'U' is on the far left:

enter image description here

I would like for the user to have full access to the buttons. This might mean that the button could be cut off, but on a page swipe it would be fully visible. Or it could mean that the button would not show on screen if it would be cut off.

What I have tried:

  • I tried to turn off paging, which works but we would greatly prefer paging in this case so it is a last resort.
  • My biggest effort was trying to group the buttons based on how many would fit into a screen. The idea was to group the buttons into "pages" and scroll the different pages. Because the buttons are different sizes, I have to read the sizes as they are rendered onto the screen. I'm not nearly an expert in this, and the closest I could come to do this was in a didMoveToWindow() method on the toolbar button view class (UIView). But this would sometimes have the button sizes and sometimes did not have the button sizes. I don't know why. The buttons did not yet have sizes if I put the code in the initializer for the class, nor did they have sizes when initializing the scroll view for the accessory view. The didMoveToWindow() was the only method I found that gave sizes, but even that was not 100%.
    override func didMoveToWindow() {
        var buttonSizeArray: [CGFloat] = []
        for button in op1ButtonList {
            buttonSizeArray.append(button.frame.width)
        }
        let buttonSpacing: CGFloat = 12
        let leadingSpacing: CGFloat = 10
        
        var sizeDict: [Int:CGFloat] = [:]

        for (index, buttonSize) in buttonSizeArray.enumerated() {
            if index == 0 {
                sizeDict[index] = leadingSpacing + buttonSize
            } else {
                sizeDict[index] = buttonSpacing + buttonSize + sizeDict[index - 1]!
            }
        }

        for index in 0..<buttonSizeArray.count {
                if sizeDict[index]! < UIScreen.main.bounds.size.width {
                    // keep track of the last button that fit on the screen
                    continue
                }
                break
            // code to group the buttons into views for the scroll view to use
        }
    }

In working with scroll views in this way, have others run into this and found a good solution? The answers I have found mainly point the developer to get the page sizes right so the views will contain the intended content, but in this case I haven't found a way to consistently get the sizes I need. I am definitely open to other solutions as well.

0 Answers
Related