Not 100% sure if it's caused by the anchor as I just removed it and haven't experienced crash so far (will report back if more crashes happens) - could someone check and help see if that could actually be where the bug is? Going to file an Apple bug as well.
My view looks like this:
var body: some View {
ScrollViewReader { scrollProxy in
ScrollView {
if isShowingContent {
LazyVStack {
ForEach(mo.msgMos.indices, id: \.self) { i in
...
}
}
}
}
.onChange(of: mo.scrollToIdx) { idx in
withAnimation {
scrollProxy.scrollTo(targetIdx, anchor: .center)
}
}
}
}
And the crash stack looks like this:
Crashed: com.apple.main-thread
0 AttributeGraph 0x1cedce974 AGGraphGetValue + 284
1 SwiftUI 0x1addcbe5c _ViewCache.layout.getter + 52
2 SwiftUI 0x1addcc2f4 _ViewCache.withPlacementData<A>(_:) + 160
3 SwiftUI 0x1addd02d0 closure #1 in IncrementalScrollable.makeTarget(at:anchor:) + 336
4 SwiftUI 0x1addd6a9c partial apply for closure #1 in IncrementalScrollable.makeTarget(at:anchor:) + 56
5 SwiftUI 0x1ae2241fc HostingScrollView.updateAnimationTarget(_:) + 216
6 SwiftUI 0x1ae2245c4 HostingScrollView.bounds.didset + 188
7 SwiftUI 0x1ae2244e8 HostingScrollView.bounds.setter + 128
8 SwiftUI 0x1ae22444c #objc HostingScrollView.bounds.setter + 44
9 UIKitCore 0x1aa494e4c -[UIScrollView setContentOffset:] + 804
10 UIKitCore 0x1aa48f1e0 -[UIScrollViewScrollAnimation setProgress:] + 320
11 UIKitCore 0x1a95094b8 -[UIAnimator _advanceAnimationsOfType:withTimestamp:] + 276
12 QuartzCore 0x1aa8e46a4 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 664
13 QuartzCore 0x1aa9bb1a0 display_timer_callback(__CFMachPort*, void*, long, void*) + 280
14 CoreFoundation 0x1a7633ce4 __CFMachPortPerform + 176
15 CoreFoundation 0x1a7658098 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60
16 CoreFoundation 0x1a7657440 __CFRunLoopDoSource1 + 596
17 CoreFoundation 0x1a7651320 __CFRunLoopRun + 2360
18 CoreFoundation 0x1a76504bc CFRunLoopRunSpecific + 600
19 GraphicsServices 0x1be0d5820 GSEventRunModal + 164
20 UIKitCore 0x1a9ff4734 -[UIApplication _run] + 1072
21 UIKitCore 0x1a9ff9e10 UIApplicationMain + 168
22 Fablur 0x102453f8c main + 12 (AppDelegate.swift:12)
23 libdyld.dylib 0x1a7317e60 start + 4
I've found that if you use scrollTo with anchor and it positions the contents of the scrollview to a position it wouldn't normally be able to reach through normal scrolling, then it will crash when the view is removed.
For example. Scrolling to the last view in a scrollview and using a .leading or .center position.
I've fixed this by adding a blank view to the end of my scrollview. Not ideal but works.
Remove the withAnimation block and you'll be fine
.onChange(of: mo.scrollToIdx) { idx in
scrollProxy.scrollTo(targetIdx, anchor: .center)
}
I assume it should be attached in different place
var body: some View {
ScrollViewReader { scrollProxy in
ScrollView {
if isShowingContent {
LazyVStack {
ForEach(mo.msgMos.indices, id: \.self) { i in
...
}
}
.onChange(of: mo.scrollToIdx) { idx in
withAnimation {
scrollProxy.scrollTo(targetIdx, anchor: .center)
}
}
}
}
}
}
I've had very similar problems and came to the (potential) conclusion that the ScrollViewReader doesn't calculate properly because your content is in a LazyVStack and since the Lazy items don't preload... the reader doesn't know how long the scrollview actually is. This is my guess at least...
Yet another crash reason I found was the attempt to scroll an empty scroll view. So before attempting to scroll, check your view model whether the scroll view would be empty.
Related
I need to create a line like the image below. Does anyone have any suggestions?
target image
In addition to the mentioned image, it is necessary to select the line with the mouse, which can be done with TapHandler.
You can consider creating it with PathSvg.
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
Page {
background: Rectangle { color: "black" }
Frame {
anchors.centerIn: parent
padding: 0
width: 162
height: 80
background: Rectangle { color: "#444" }
Shape {
ShapePath {
strokeColor: "white"
PathSvg {
path: "M 0 20 L 155 59
155 57.5 162 60 155 62.5 155 61 0 22 z"
}
}
}
}
}
You can Try it Online!
Or you can consider implementing it as SVG:
import QtQuick
import QtQuick.Controls
Page {
background: Rectangle { color: "black" }
Frame {
anchors.centerIn: parent
padding: 0
background: Rectangle { color: "#222" }
Image {
source: "sample.svg"
sourceSize: Qt.size(width, height)
width: 128
height: 80
}
}
}
// sample.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 20">
<path stroke="white" stroke-width="0.4" fill="white" d="M 0 4 L 31 11.8
31 11.5 32 12 31 12.5 31 12.2 0 4.4 z"/>
</svg>
You can Try it Online!
Since the update to iOS14, the textbox is no longer expanded so that the arrows no longer adapt to the different lengths of text.
As shown in the gif, the text width remains and too long content is cut short with an ellipsis. Can you help me how to update my code?
#State var teamName: [String] = ["blue", "red", "green", "yellow"]
[…]
HStack(spacing: 5) {
Image(systemName: "arrowtriangle.left.fill")
.font(Font.system(size: 12 ,weight: .regular))
Text(teamName[selectedLeftTeam])
.font(Font.system(size: 24 ,weight: .bold, design: .monospaced).smallCaps())
Image(systemName: "arrowtriangle.right.fill")
.font(Font.system(size: 12 ,weight: .regular))
}
.foregroundColor(Color("primaryColor")).opacity(0.2)
.gesture(
DragGesture()
.onChanged({
action in
self.swipeOffsetX = Double(action.translation.width * 0.75)
})
.onEnded({
action in
let left = self.swipeOffsetX < 30
let right = self.swipeOffsetX > 30
if left { self.selectedLeftTeam += 1 }
if right { self.selectedLeftTeam -= 1 }
self.swipeOffsetX = 0 // reset
})
)
You can use fixedSize to make your Text use as much space as it's necessary:
Text(teamName[selectedLeftTeam])
.font(Font.system(size: 24 ,weight: .bold, design: .monospaced).smallCaps())
.fixedSize()
You can also limit it to one dimension only - if you want to do it horizontally:
.fixedSize(horizontal: true, vertical: false)
I have the following code:
#State private var couponId: Int = 0
var body: some View {
ScrollView {
VStack(spacing: -50) {
ForEach(1...20, id: \.self) { index in
CouponCell()
.zIndex(couponId == index ? 2 : 0)
.animation(.spring())
.onTapGesture {
withAnimation {
couponId = index
}
}
}
}
.padding().frame(maxWidth: .infinity, maxHeight: .infinity)
The the user selects a particular CouponCell then I update the Zindex so it appears on top of other cells. This works but it does not animate at all. What am I missing and why animation is not taking place.
I am using Xcode 12 Beta 2 on macOS Big Sur Beta 2
The .zIndex itself is not animatable modifier, because actually nothing to animate in view z position - it is either below or above.
Probably you meant (or would prefer) something combined like the following
Tested on replicated code (Xcode 12)
CouponCell()
.zIndex(couponId == index ? 2 : 0)
.scaleEffect(couponId == index ? 1.02 : 1)
.animation(.spring(), value: couponId)
.onTapGesture {
couponId = index
}
The text inside my chatbubbles won't break in new line.
Here's the "chatbubble" extracted in an own view
struct chatPartnerBubble: View {
var textMsg: String
var body: some View {
VStack(alignment: .leading) {
HStack {
HStack {
Text(textMsg)
.foregroundColor(Color.white)
.padding(10)
.lineLimit(nil)
}
.background(Color.blue)
.cornerRadius(12)
Spacer()
}.padding(.leading)
}
}
}
and here is the ChatView
ScrollView {
VStack {
chatPartnerBubble(textMsg: "text")
chatPartnerBubble(textMsg: "text")
chatPartnerBubble(textMsg: "text")
chatPartnerBubble(textMsg: "text")
chatPartnerBubble(textMsg: "text")
chatPartnerBubble(textMsg: "text")
}
}
But if the textMsg is longer, it just dots..., and does not break into new line
You can achieve the desired functionality by choosing List over Scrollview. If we consider scalability factor in our chatting app then List is far better than Scrollview. Because views can be easily reusable in List.
struct chatPartnerBubble: View {
var textMsg: String
var body: some View {
VStack{
Text(textMsg)
.foregroundColor(Color.white)
.padding(10)
.lineLimit(nil)
}
.background(Color.blue)
.cornerRadius(12)
}
}
struct ContentView: View {
var body: some View {
List {
chatPartnerBubble(textMsg: "text1 111111111 1 11111111 1 1 1 1 1 1 1 1 111111111111")
chatPartnerBubble(textMsg: "text2 22222 222222222 2222222222222 222 2 2 2 22 2 222222")
chatPartnerBubble(textMsg: "text3 333333 3 333 333 3 3 3 3 33333333 3 33333333 3333333")
}
.padding(.top)
.onAppear {
UITableView.appearance().separatorColor = .clear
}
.onDisappear {
UITableView.appearance().separatorColor = .gray
}
}
}
In case we have more than one table view in our app, so OnAppear and onDisappear blocks are used to hide/show seperator only for above message table view.
I seems to work fine for me, I'm using Xcode 11.2 Beta 2, so the Xcode version might be the problem. I remember I had a similar problem before and the solution was VStack(alignment: .center, spacing: 0) maybe it helps
I am making a swiftUI calendar and met a weird truncation problem of SwiftUI Text View.
struct test : View {
var body: some View {
GeometryReader { geometry in
HStack(alignment: .center, spacing: 0) {
ForEach(0..<7) { _ in
Text("Tue").frame(width: geometry.size.width / 7).border(Color.red, width: 2)
}
}
}
}
}
In the beginning, I thought it might be because the Text View size is not big enough. But when I decrease the Text View Width, the truncation is gone. I also tried to set a smaller font and it didn't work too. Thanks for any hint!
struct test : View {
var body: some View {
GeometryReader { geometry in
HStack(alignment: .center, spacing: 0) {
ForEach(0..<7) { _ in
Text("Tue").frame(width: geometry.size.width / 8).border(Color.red, width: 2)
}
}
}
}
}
Beta 5
In beta 5 it seems the problem has been resolved.
Beta 4 and Previous
It is definitely a bug that only shows in the iPhone XS, but not with the iPhone XR. Note that the XS is 375 points wide, while the XR is 414 points. However, that has nothing to do with it. 375 is more than enough to fit the 7 labels.
I think you should submit a bug report, and in the meantime, use the XR for development. If anyone has an actual device, it would be nice to know if the bug is also present there.
I created this small example that shows how erratically it works on the Xs
And here is the Xr, which works as it should:
Here's the code of the example:
struct ContentView: View {
#State private var slider: Float = 100.0
var body: some View {
VStack {
GeometryReader { geometry in
HStack(alignment: .center, spacing: 0) {
ForEach(0..<7) { _ in
Text("Tue").frame(width: geometry.size.width / 7, height: 30).border(Color.blue)
}
}
}.frame(width: Length(slider), height: 40)
Text("\(slider)")
Slider(value: self.$slider, from: 100.0, through: 375.0, by: 1.0)
Spacer()
}
}
}