一个用于 macOS 和 iOS 的自定义步进文本字段(Swift/SwiftUI/Objective-C/Catalyst)。
我喜欢 SwiftUI 设置面板中使用的视觉方法,而不是 macOS 上传统的上下步进控件那种 *非常* 小的点击目标。
IBDesignable
支持,因此您可以在 Interface Builder 中查看和配置您的步进视图。通过 Swift Package Manager 将 DSFStepperView
添加到您的项目,或将 Sources/DSFStepperView 中的源文件直接复制到您的项目。
演示可在 Demo/
子文件夹中找到。
使用 Interface Builder 添加一个新的 NSView
或 UIView
实例,然后将类类型更改为 DSFStepperView
。
let stepperView = DSFStepperView(frame: .zero)
stepperView.minimum = -1.0
stepperView.maximum = 1.0
stepperView.allowsEmpty = true
...
// Set the control's value to 0.5
stepperView.floatValue = 0.5
// Clear the control's value
stepperView.floatValue = nil
有四种方法可以动态接收值更新。
在一个对象上实现协议 DSFStepperViewDelegateProtocol
,并将其设置为 DSFStepperView
实例的委托。值的更新将通过以下方式接收
func stepperView(_ view: DSFStepperView, didChangeValueTo value: NSNumber?)
接口。
您可以通过步进视图上的 onValueChange
属性提供一个闭包来调用。
self.stepper.onValueChange = { [weak self] newValue in
Swift.print("Ordinal value did change to \(String(describing: newValue)) ")
}
您可以使用 Combine 框架来订阅控件中的更改。在 10.15 及更高版本上,控件公开了发布者 publishedValue
,您可以从中订阅值更改。
self.cancellable = myStepper.publishedValue.sink(receiveValue: { currentValue in
if let c = currentValue {
print("stepper is currently at \(c)")
}
else {
print("stepper is currently empty")
}
})
您可以使用绑定来观察 numberValue
成员变量。
self.stepperObserver = self.observe(\.stepper.numberValue, options: [.new], changeHandler: { (_, value) in
guard let val = value.newValue else { return }
Swift.print("\(val)")
})
如果您想允许非整数值(例如 0.5),您需要提供一个 NumberFormatter
实例来格式化和验证该字段中的值。 DSFStepperView
提供了一个默认的 NumberFormatter,它提供范围为 (-∞ ... ∞) 的仅整数值,您可以覆盖它。
使用数字格式化程序还可以让您拥有一个支持(例如)显示 1st、2nd、3rd、4th 的步进器。
let format = NumberFormatter()
format.numberStyle = .decimal
// Always display a single digit fractional value.
format.allowsFloats = true
format.minimumFractionDigits = 1
format.maximumFractionDigits = 1
stepperView.numberFormatter = format
在 Interface Builder 中,您可以将实例的 numberFormatter
outlet 连接到 xib 或 storyboard 中的 NumberFormatter 实例。
您可以使用 Interface Builder 以通常的方式或通过编程方式为整个控件指定工具提示。
myStepperInstance.toolTip = "groovy!"
您还可以通过委托上的可选函数为步进器的组件提供单独的工具提示。
@objc optional func stepperView(_ view: DSFStepperView, wantsTooltipTextforSegment segment: DSFStepperView.ToolTipSegment) -> String?
使用此方法,您可以为以下步进器部分提供自定义工具提示。
所有这些属性都可以通过 Interface Builder 或以编程方式进行配置。
allowsEmpty
:允许字段为空。如果您想显示(例如)“继承”或“默认”标签,这将非常有用 (Bool
)。placeholder
:字段为空时要使用的占位符字符串 (String
)。minimum
:视图中允许的最小值 (CGFloat
)。maximum
:视图中允许的最大值 (CGFloat
)。increment
:使用按钮时递增或递减的量 (CGFloat
)。initialValue
:要在字段中显示的初始值(仅对 @IBDesignable 支持有用) (CGFloat
)。fontName
:显示值的字体的名称(例如,Menlo)。如果无法在系统上解析 fontName,则默认为系统字体 (String
)。fontSize
:显示值的字体的大小(以磅为单位) (CGFloat
)。foregroundColor
:显示值的字体的颜色 (NSColor
/UIColor
)。indicatorColor
:在控件底部绘制小数值条的颜色 (NSColor
/UIColor
)。numberFormatter
:一个可选的数字格式化程序,用于格式化/验证视图中的值。isEnabled
:启用或禁用控件。font
:文本字段的字体。提供了一个 SwiftUI 包装器,支持 iOS 和 macOS。 Demo
子文件夹中有一个用于 iOS 和 macOS 的演示项目。
struct ContentView: View {
@State private var currentValue: CGFloat? = 23
@State private var isEnabled: Bool = true
let configuration = DSFStepperView.SwiftUI.DisplaySettings(
minimum: 0, maximum: 100, increment: 1
)
let style = DSFStepperView.SwiftUI.Style(
font: DSFFont.systemFont(ofSize: 24, weight: .heavy),
indicatorColor: DSFColor.systemBlue)
var body: some View {
DSFStepperView.SwiftUI(
configuration: self.configuration,
style: self.style,
isEnabled: self.isEnabled,
floatValue: self.$currentValue,
onValueChange: { value in
Swift.print("New value is \(String(describing: value))")
}
)
}
}
4.0.0
:
3.0.0
: 在包中显式定义静态和动态库。2.0.1
: 修复了 issue 42.0.0
:
floatValue
分离为 floatValue
(仅 Swift)和 numberValue
(用于 objc 的 NSNumber)。 如果您在 XIB 中使用了先前观察 floatValue
的绑定,则需要更新它们以改用 numberValue
。1.1.4
: 添加了 Objc 演示,修复了委托可见性。1.1.3
: 修复了默认 SwiftUI 初始化程序未导出的问题。1.1.2
: 一些可访问性更新。1.1.1
: 修复了 Combine 在 10.15 之前不可用的问题。1.1.0
: 为按钮添加了鼠标悬停高亮显示,Combine 发布者 (10.15+),SwiftUI 包装器 (10.15+)。1.0.2
: 修复了 10.14 及更早版本未显示该值的问题(NumberFormatter 更改)。1.0.1
: 修复了关于 Big Sur 上按钮标签消失的 Bug #1。1.0.0
: 初始版本。MIT。 随意使用,只需署名我的作品即可。 如果您在某个地方使用了它,请告诉我,我很乐意听到它!
MIT License
Copyright (c) 2021 Darren Ford
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.