admin管理员组文章数量:1122832
When using a stylus or a mouse on the iPad, hovering over a text button causes it to get highlighted. Unfortunately, the highlighted area does not match the size of the button. How can I make hover-highlighted area to match the size of the button?
Here is an image to demonstrate it (notice the pale gray hover and red border of a real button)
And here is the min.code to see for yourself (run in the simulator and use "Capture Pointer" (looks like a "sun with rays" button)):
struct SOQuestionView: View {
var body: some View {
NavigationStack {
Text("Hello, World!")
.toolbar {
ToolbarItemGroup(placement: .principal) {
Button("B") {}
.border(Color.red)
}
}
}
}
}
P.S. Why do I need it? - I want to give background to that button. But when I hover over it, you guessed it - the hover background doesn’t align with the actual button's background.
When using a stylus or a mouse on the iPad, hovering over a text button causes it to get highlighted. Unfortunately, the highlighted area does not match the size of the button. How can I make hover-highlighted area to match the size of the button?
Here is an image to demonstrate it (notice the pale gray hover and red border of a real button)
And here is the min.code to see for yourself (run in the simulator and use "Capture Pointer" (looks like a "sun with rays" button)):
struct SOQuestionView: View {
var body: some View {
NavigationStack {
Text("Hello, World!")
.toolbar {
ToolbarItemGroup(placement: .principal) {
Button("B") {}
.border(Color.red)
}
}
}
}
}
P.S. Why do I need it? - I want to give background to that button. But when I hover over it, you guessed it - the hover background doesn’t align with the actual button's background.
Share Improve this question asked Nov 23, 2024 at 5:17 AnnaAnna 717 bronze badges 1- That gray rectangle is supposed to be an enlarged version of the pointer. It doesn't make sense for it to fit exactly inside the button's border. You can even slightly move the gray rectangle around. – Sweeper Commented Nov 23, 2024 at 8:45
2 Answers
Reset to default 1The default hover effect depends on the ButtonStyle
used for the button.
The button style in your example is
.automatic
and the default effect is.highlight
.None of the other built-in button styles seem to have a default hover effect, but you can turn an effect on by applying a
.hoverEffect
modifier.
So one workaround for the mis-fitting highlight shape is to use a button style with a more defined size and apply .hoverEffect(.highlight)
to it.
If you choose
.plain
or.borderless
as button style then you will probably want to add padding too.If you want the hover effect to be shown as soon as the mouse cursor enters the frame, as opposed to when it reaches the text of the label, apply
.contentShape(Rectangle())
to the padded button.
Using this approach with your example:
Button("B") {}
.buttonStyle(.borderless)
.padding()
.contentShape(Rectangle())
.hoverEffect(.highlight)
.border(.red)
If you want to use the same modifiers for other buttons too, it would be simpler to define a custom ButtonStyle
that encapsulates this styling and behavior:
struct MyHoverButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.contentShape(Rectangle())
.foregroundStyle(.tint)
.hoverEffect(.highlight)
}
}
Button("B") {}
.buttonStyle(MyHoverButtonStyle())
.border(.red)
With a custom button style, you could also apply your own styling when hover is in effect:
- Detect hover state yourself using an
.onHover
callback. - A
.transition
can be used to add a bit of animation.
struct MyHoverButtonStyle: ButtonStyle {
@State private var withHover = false
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.foregroundStyle(.tint)
.background {
if withHover {
RoundedRectangle(cornerRadius: 10)
.fill(.yellow.opacity(0.5))
.scaleEffect(1.1)
.transition(.scale.animation(.easeInOut(duration: 0.1)))
}
}
.onHover { isHovering in
withHover = isHovering
}
}
}
This is the .highlight
hover effect.
For pointer input this effect morphs the pointer into a platter behind the view and shows a light source indicating position.
The gray rectangle is not a fixed shape that highlights the button, but rather the pointer itself. It is not designed to fit the button's frame - you can move it around just like a normal pointer. The actual position of the pointer is indicated by a "light source" - an area where the gray color is slightly lighter.
Unfortunately making your own hover effects is not an option on iOS (only available on visionOS), so if you want to change the highlight's frame to fit the button, you can try something like in Benzy Neez's answer.
You can remove the effect simply using .hoverEffectDisabled()
, without changing the button style.
Alternatively, if you still want something to happen on hover, you can use .defaultHoverEffect(.lift)
, which just enlarges the button a little bit, and IMO doesn't look as bad.
本文标签: swiftuiHow to change the size of onHover background of a buttonStack Overflow
版权声明:本文标题:swiftui - How to change the size of onHover background of a button? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736299521a1930485.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论