1

我需要考虑的文本视图数量未知(睡眠期间经过的时间)。每个文本视图只有一个小时,例如 Text("12")、Text("1") 等。

我需要知道所有组合小时文本视图的宽度,以便我可以从整体几何中相应地减去空间。下面是一个widthOfString可能与 UIKit 一起使用但似乎无法在 SwiftUI 中计算正确大小的函数。我怎样才能做到这一点?

示例用法:

  Spacer()
    .frame(width: CGFloat(hourAsDate.timeIntervalSince(hoursBetweenSleepStartAndEnd[(hoursBetweenSleepStartAndEnd.firstIndex(of: hourAsDate) ?? 0) - 1]) / totalSleepSeconds)  * calculateSpaceOfHourText())
  Text("\(calendar.component(.hour, from: hourAsDate))")
    .font(Font.system(size: 13.0))
  Spacer()
    .frame(width: CGFloat(sleepEndDate.timeIntervalSince(hourAsDate) / totalSleepSeconds)  * calculateSpaceOfHourText())

我的助手功能和扩展:

       //helper
    private func calculateSpaceOfHourText() -> CGFloat {
    
    //The idea here is to try to add up all the space that is taken up by hour Text views and subtract it from the total with of geometry
    
        var hoursToUseForCalculationOfSpace = hoursBetweenSleepStartAndEnd
        
        if hoursBetweenSleepStartAndEnd.first ?? Date() <= sleepStartDate {
            hoursToUseForCalculationOfSpace.removeFirst()
        }
        
        if hoursBetweenSleepStartAndEnd.last ?? Date() >= sleepEndDate {
            hoursToUseForCalculationOfSpace.removeLast()
        }
        return (proxy.size.width - hoursToUseForCalculationOfSpace.map { calendar.component(.hour, from: $0) }.map { "\($0)".widthOfString(usingFont: UIFont.systemFont(ofSize: 13, weight: .regular)) }.reduce(0, +))
    }
}

extension String {
   func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        //print("THIS width = \(size.width)")
        return size.width
    }
}
4

1 回答 1

0

不能直接回答您的问题,但也许要研究的方向是PreferenceKeyGeometryReader. 例如下面的代码RoundedRectangle在背景中用它修改的视图的高度绘制一个:

struct HeightPreferenceKey: PreferenceKey {
    static var defaultValue: [CGFloat] = []
    
    static func reduce(value: inout [CGFloat], nextValue: () -> [CGFloat]) {
        value.append(contentsOf: nextValue())
        
    }
    
    typealias Value = [CGFloat]
}

struct HeightPreferenceViewSetter: View {
    var body: some View {
        GeometryReader { geometry in
            RoundedRectangle(cornerRadius: 13)
                .fill(Color.gray)
                .preference(key: HeightPreferenceKey.self,
                            value: [geometry.size.height]) 
              }
    }
}
struct HeightModifier: ViewModifier {
    func body(content: Content) -> some View {
        content
            .background(HeightPreferenceViewSetter())
            
    }
}
于 2021-04-20T20:13:39.133 回答