0
votes

I have a ScrollView in which I place a number of different Views. The scrollview does not scroll though - it bounces back from the content view extremes. Is the face I'm manually placing the views the problem? Is there a way to set the scrollviews content view width like in UIKit?

I've updated the code here to be a standalone version. The function placing the views is the same as before. The scrollview is behaving the same too...

import SwiftUI

struct ContentView: View {

var circleArray: [CircleView] = [CircleView(id:1), CircleView(id:2), CircleView(id:3), CircleView(id:4), CircleView(id:5), CircleView(id:6), CircleView(id:7), CircleView(id:8), CircleView(id:9), CircleView(id:10), CircleView(id:11), CircleView(id:12), CircleView(id:13), CircleView(id:14), CircleView(id:15), CircleView(id:16), CircleView(id:17), CircleView(id:18), CircleView(id:19), CircleView(id:20), CircleView(id:21), CircleView(id:22), CircleView(id:23), CircleView(id:24), CircleView(id:25)]

var body: some View
{
    ScrollView(.horizontal, showsIndicators: false)
    {
        GeometryReader
        {
            scrollViewGeometry in
            ForEach(circleArray)
            { circle in
                let circleFrame = getFrameFor(circle: circle, minWidth: 75)
                ZStack()
                {
                    Circle().fill(Color.red)
                }
                .position(x: circleFrame.origin.x, y: scrollViewGeometry.size.height - (circleFrame.size.height/2) - circleFrame.origin.y)
                .frame(width: circleFrame.size.width, height: circleFrame.size.height, alignment:.center)
            }
        }
    }.padding()
}

func getFrameFor(circle: CircleView, minWidth:CGFloat) -> CGRect
{
    var thisFrame = CGRect()
    var frameWidth = minWidth
    let numberOfHexagonsWide = sqrt(Double(25)) + floor(Double(sqrt(Double(25))/2))
    let widthOfHexagonViews = (Double(frameWidth) * 0.8) * numberOfHexagonsWide
    let xMargin = (Double(frameWidth) - widthOfHexagonViews) / 12
    var xStartingPosition = 0
    var xPosition = 0
    var yStartingPosition = 1
    var yPosition = 1
    var yEndPosition = 1
    
    if minWidth < 75
    {
        frameWidth = 75
    }
    
    for index in 0...24
    {
        let actualXPosition = Double(xPosition) * (0.5 * Double(frameWidth))
        let actualYPosition = Double(yPosition) * (0.8 * Double(frameWidth)) + (0.2 * Double(frameWidth))
        
        
        thisFrame = CGRect(x: actualXPosition + xMargin, y: actualYPosition, width: Double(frameWidth), height: Double(frameWidth))
        
        if yPosition == yEndPosition
        {
            if Double(yStartingPosition) < sqrt(Double(25))
            {
                yStartingPosition += 1
                xStartingPosition += 1
            }
            else
            {
                yEndPosition += 1
                xStartingPosition += 2
            }
            yPosition = yStartingPosition
            xPosition = xStartingPosition
        }
        else
        {
            xPosition += 1
            yPosition -= 1
        }
        
        if circle.id - 1 == index
        {
            return thisFrame
        }
        
    }
    return thisFrame
}

struct CircleView: Identifiable
{
    var id: Int
}
        
}
1
This cannot be tested, would you provide minimal reproducible example? - Asperi
@Asperi - I changed the code to make it standalone. Do you have any advice about how to get the ScrollView to work properly? - HillInHarwich

1 Answers

0
votes

The was solved by wrapping the views in an HStack within the ScrollView, and setting the width.