Post

Replies

Boosts

Views

Activity

ScrollView triggers (almost) endless View redrawing.
I am developing a MacOS app with a vertically oriented ScrollView. Inside that View I use a LazyVStack. In the LazyVStack I have a column of images. I want the images to occupy as much of the LazyVStack width as possible so I created a frame for the VStack with a maxWidth: .infinity. When the user grabs the edge of the window and drags it to reduce the window width, the Views of the window adjust themselves to fit the reduced space. This includes reducing the width of the images. I maintain a fixed aspect ratio for the images, so the height of the images is reduced too. My problem arises when the width of the images (and height) reduces to the point where the scroll bar is no longer needed because all of the images fit within the height of the ScrollView, and the ScrollView removes the scroll bar. That triggers a redraw of the images, with a slightly bigger size because the width used by the scroll bar is now available. When the the images get bigger they don't all fit within the height of the ScrollView anymore and the scrollbar is restored. That, of course, reduces the space available for the images, so they are reduced in size again - which then triggers the ScrollView to remove the scrollbar again. The whole thing goes into a spasm of flickering images (bigger and smaller) and scrollbar (off and on) until finally I get the dreaded error message: The window has been marked as needing another Display Window pass, but it has already had more Display Window passes than there are views in the window. There seems to be no way to prevent this behavior by setting an option on the ScrollView. It would be great if one could indicate that the scroll bar should always remain visible, or at least that the space occupied by the scroll bar remain, even if it is just empty. The only way I could solve this problem was to go through a somewhat involved calculation to set the image width in such a way that it still responds to window width changes (and some other size changes I allow in some of the other app's Views). This complication would not be necessary if there were better controls on the scroll bar. Is there a reason for not providing adequate controls for the ScrollView? Its uncontrollable behavior complicates the programming.
0
0
83
1d
Regex Builder error message???
I'm debugging some Regex Builder code in my Playground. I run the following piece code: let timeMatchWithout = possibleTime.firstMatch(of: timeWithoutSec) and I get this error message: Regex.Match optional storedCapture contains no some What could this possibly mean? contains no some??? Here is a more complete snippet, if this helps: let hourRef = Reference<Substring>() let minuteRef = Reference<Substring>() let hourReg = Regex { ChoiceOf { Capture(as: hourRef) { One(.digit) One(.digit) } Capture(as: hourRef) { One(.digit) } } } let minuteReg = Regex { ChoiceOf { Capture(as: minuteRef) { One(.digit) One(.digit) } Capture(as: minuteRef) { One(.digit) } } } let ampmRef = Reference<Substring>() let ampmReg = Regex { Capture(as: ampmRef) { ZeroOrMore { ChoiceOf { One("am") One("pm") One("a.m.") One("p.m.") } } } /* transform: { $0.lowercase } */ }.ignoresCase() let timeWithoutSec = Regex { hourReg One(":") minuteReg ZeroOrMore(.whitespace) ampmReg }.ignoresCase() let possibleTime = "10:20 AM" let timeMatchWithout = possibleTime.firstMatch(of: timeWithoutSec) The last line produces the error message. Thanks for the help. Note the removed transform: on the ampmReg definition. If that is included the compiler times out as noted in my previous post, yesterday.
2
0
572
May ’24
Swift Regex Builder issue
Why does this Regex Builder code in my SwiftUI app not work? I'm parsing a string that might be a date and time with either AM or PM specified for the time. This bit of code looks for the optional AM or PM. The error I get is: The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions What would 'distinct sub-expressions' mean in this case? The code: let ampmRef = Reference<Substring>() let ampmReg = Regex { Capture(as: ampmRef) { ZeroOrMore { ChoiceOf { One("am") One("pm") } } } transform: { $0.lowercase } }.ignoresCase() In a related question, is there a way to return a default if the ChoiceOf fails both AM and PM?
3
0
659
May ’24
Seems like odd xcode and/or Swift behavior
I'm writing a little Swift app to report IP addresses that attack my Wordpress websites. I made a little mistake in one file which revealed an xcode behavior which seems like a bug. When I try to Build the code xcode says it failed. A failure message appears in the Issues, but after a few seconds the failure message disappears. No line of code is ever marked as having an issue. But the build definitely fails. Included here is a little bit of code which illustrates the issue. It is just a struct and closure definition. If you create a little project and add the code you can try to build it. Cmnd-B is all you need to do. Sometimes the error message doesn't even appear in Issues at all even though the Build fails. Just try Cmnd-B a couple times and you should see it appear for a few seconds. Can you spot the error in this code? There is an errant return statement in the closure. Change in return to just in and is should build OK. But what is going on with the transient Build error message that disappears and the failure to mark any lines of code? Is this not an xcode/swift bug? I'm using xcode 14.2 and the latest Swift. import Foundation class weirdBehavior: NSObject { // Construct a struct which defines the data to be saved for each reported bad IP // This struct is used to generate JSON strings. struct savedBadIP: Codable { var ip: String var reason: String var attackDateString: String var reportedDateString: String var responseError: Bool var responseConfidence: Int var responseDetail: String } func weirdBehaviorExample() { let dateFormatter = DateFormatter() let checkForRecentDate : (savedBadIP, savedBadIP) -> Bool = {badIP1, badIP2 in return let date1 = dateFormatter.date(from: badIP1.reportedDateString)! let date2 = dateFormatter.date(from: badIP2.reportedDateString)! let diff: TimeInterval = date2.timeIntervalSince(date1) return diff < 0.0 // Return false if date2 is before date1 } } }
0
0
330
Feb ’23
NSTableView updating
I have an NSTableView which shows the longitude and latitude points of objects on a map. Some objects, like trails, have many rows in the table. When I change objects I want to update the NSTableView and then select row 0. I tried [obectCoordTable reloadData]; [objectCoordTable selectRowIndexes: [NSIndexSet indexSetWithIndex: 0] byExtendingSelection: NO];This does not work because reloadData does not reload the table. It only schedules a reload for some time later(on next iteration of Main Loop?). So my attempt to select row 0 happens first. Then just before the tabledata are reloaded a (void)tableViewSelectionDidChange: happens with selected row reset to -1. So myselection of row 0 is ineffective.How do I select row 0 after the reload is finished? There seems to be no delegate method to notify the userwhen a complete data reload is completed.Do I have to schedule the selectRowIndexes for execution at a later time and hope it is after the data reload? That might work but seems a bit too hokey?Thanks.Richard Stover
3
0
1.4k
Jun ’20
Text along a curve
I would like to draw text along a complex bezier curve. I've seen several examples on the web using CGPathApplyto do this. But those examples seem to be wrong. CGPathApply does not supply you with a series of points alongthe curve. I just get back the points, and control points, I just used to specify the Bezier curve. I want actualpixel coordinates of points along the curve. Is there some way to do this? Do I have to write my ownfunction to reproduce the Bezier curve points given the end points and control points? Has Apple documentedexactly the algorithm they use for doing this? Or is there some CG function I have overlooked thatdoes the evaluation for me? Or is there a CG function that takes a string and a path as arguments anddoes the job for me?Thanks.
7
0
2.0k
May ’20
How to save GPU frames to video
I have created a 3D model of a local outdoor performance space and I have an app that usesMetal on MacOS 10.14.2 to display the model. I want to create an animationby flying the camera around the scene, while record each frame. I know how to dothe animated fly-around and I know how to create a video frame-by-frame withAVFoundation. The step for which I can find no information is how I can capture each frame.I have a completion handler so I know when the gpu has finished each command buffer.But what is the best way to get the image in space?I thought perhaps I could do this by attaching a second texture to colorAttachments[1]but this has resulted in some odd behavior where the original scene that used to fill myMTKView window now occupies just the upper left quadrant of the window.What I was trying to do is write the same color to both colorAttachments[0] (my screen) and tocolorAttachments[1]. In my shader I defined:struct FragmentOut { float4 color0 [[ color(0) ]]; float4 color1 [[ color(1) ]];};My fragment shader looks like:fragment FragmentOut grove_fragment_function(VertexOut vIn [[ stage_in ]], constant Uniforms &amp;uniforms [[buffer(1)]]) {....float4 color = diffuseColor + ambientColor + specularColor; out.color0 = color; out.color1 = color; return out;}My hope was that I could then use something like:offScreenTextureBuffer?.getBytes(buffer, bytesPerRow: 4 * w, from: MTLRegionMake2D(0, 0, w, h), mipmapLevel: 0)to transfer the image data to a local buffer.This doesn't seem to work, plus I have the unexpected display behavior noted above.I am configuring the offScreenTextureBuffer thus:let pixelFormat = MTLPixelFormat.bgra8Unorm_srgbvar offScreenBufferDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: pixelFormat, width: 1000, height: 600, mipmapped: false)offScreenBufferDescriptor.usage = [.renderTarget, .shaderRead]offScreenTextureBuffer = device.makeTexture(descriptor: offScreenBufferDescriptor)
3
0
3k
Jan ’19