Hi everyone, im in the process of delving more into coregraphics with swiftui, but I am at a roadblock.
First I would like to ask, what are some good resources to learn coregraphics?
Secondly:
I currently have a circle view made and what I want to do is to make my circle view modular so that it can be directly connected to another given circle by a line. How can I do this?
For example, I want my circles to represent nodes and be able to connect by lines to other nodes that are related.
Thanks in advanced.
Here is my code for the circle view:
@State private var circleProgress: CGFloat = 0
let timer = Timer.publish(every: 0.016, on: .main, in: .common).autoconnect()
private let animationDuration: TimeInterval = 1.5
@Binding var startPoint: CGPoint
@Binding var endPoint: CGPoint
var body: some View {
GeometryReader { geometry in
Canvas { context, size in
// Circle parameters
let circleSize: CGFloat = 50
let circleOrigin = CGPoint(
x: size.width / 4,
y: size.height / 2 - circleSize / 2
)
let circleRect = CGRect(
origin: circleOrigin,
size: CGSize(width: circleSize, height: circleSize)
)
let circleCenter = CGPoint(
x: circleOrigin.x + circleSize / 2,
y: circleOrigin.y + circleSize / 2
)
// Animate circle creation
var circlePath = Path()
circlePath.addArc(
center: circleCenter,
radius: circleSize / 2,
startAngle: .degrees(0),
endAngle: .degrees(360 * circleProgress),
clockwise: false
)
context.addFilter(.shadow(color: .white.opacity(0.6), radius: 5, x: 1, y: 1)) // Add white shadow
context.stroke(
circlePath,
with: .linearGradient(
Gradient(colors: [.purple, .white]),
startPoint: circleRect.origin,
endPoint: CGPoint(x: circleRect.maxX, y: circleRect.maxY)
),
lineWidth: 5
)
}
.frame(width: 300, height: 150)
.onReceive(timer) { _ in
// Update circle progress
let progressChange = 0.02 / animationDuration
if circleProgress < 1.0 {
circleProgress = min(circleProgress + progressChange, 1.0)
} else {
circleProgress = 0.0 // Reset the circle to repeat the animation
}
// Get the starting and ending points of the Canvas view
startPoint = CGPoint(x: geometry.frame(in: .global).minX, y: geometry.frame(in: .global).minY)
endPoint = CGPoint(x: geometry.frame(in: .global).maxX, y: geometry.frame(in: .global).maxY)
// Print the points for debugging
print("Start Point: \(startPoint.x), \(startPoint.y)")
print("End Point: \(endPoint.x), \(endPoint.y)")
}
}
.frame(width: 300, height: 150)
}
}
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
After uploading the app to App Store Connect, Apple automatically generated a Default App Clip Link. However, the App Clip card only opens successfully if the main app is already installed on the device. If the main app is not installed, the App Clip card displays an image and the message "App Clip Unavailable"
What could cause this behavior, and how do I ensure the App Clip works without requiring the main app to be installed?
Hi team. I am working on an app that uses the Screen Time API. I got access to the family controls (distribution) capability through the request process for my main app. I added a DeviceActivityReport extension in XCode, but haven't been able to get the extension to show up on the screen. I noticed that the extension only has the development version of the family controls capability available. Is this the source of my errors? I was able to get the screen time displayed in a test app I built where both the main app and extension used the development version of the capability, which led me to believe that discrepancy could be the issue.
Let me know if there is anything I can provide to help in the debugging process. I didn't send a minimal example in this request due to the fact that I would have to remove most of my functionality to create a "minimal" example (since the signing is only for my main app), but I can do that if needed. Thanks! I looked through the logs in the console for the phone (I'm testing on a real iPhone 13 Pro Max), but didn't see anything that popped out after looking (not exactly sure what to look for though).
STEPS TO REPRODUCE:
Create an app with the Family Controls, Distribution capability. Then create the DeviceActivityReport with the Family Control, Development capability. Attempt to see the DeviceActivityReport in the main app.
NOTE: I was successfully able to create a minimal test app completely separately that used the Development versions of the capabilities for both with the exact same extension code. That's why I think the issue could be due to the capability version discrepancy.
I want SensorKit data for research purposes in my current application. I have applied for and received permission from Apple to access SensorKit data.
During implementation, I encountered an issue in which no data was being retrieved despite granting all the necessary permissions.
I am using did CompleteFetch & didFetchResult delegate methods for retrieving data from Sensorkit. CompleteFetch method calls but where I can find different event data like Device usage, Ambient Light, etc? & didFetchResult method does not call.
Methods I am using:
1. func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest)
2. func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool
Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated.
Dear Sirs,
I'm searching for the most straightforward way to identify the root of a "Publishing changes from within view updates is not allowed, this will cause undefined behavior." warning. It is a complex SwiftUI project and I think there should be a better way than just try and error with disabling/removing and enabling/adding different screen elements to check if the warning still is shown. I tried to set a symbolic breakpoint for "os_log" in my XCode project and indeed this is triggered right before the warning appears but the callstack doesn't give me a direct hint to the part of my code which causes this warning. What would be the most direct way and is there something like an exception handler in such cases?
Thanks and best regards,
Johannes
With "Requires full screen" Split View and Slide Over are disabled but the line on the bottom of the screen remains.
How can that line removed as when a video is displayed full screen?
Topic:
UI Frameworks
SubTopic:
General
The Problem
I am trying to implement a pinch-to-zoom feature on images within a UIPageViewController. However, often times when trying to pinch to zoom, the magnification gesture gets overridden by the scrolling gesture built into the UIPageViewController. I'm not sure how to get around this. The Apple Photos app seems to allow pinch to zoom on photos inside a full-page scrolling view without any issue, so I believe it should be possible.
Versions: iOS 17.2.1 - iOS 18.2.1, Swift (SwiftUI), Xcode 15.1
Steps to Reproduce
Run this sample Xcode project on a physical device: https://drive.google.com/file/d/1tB1QyY6QPEp-WLzdHxgDdkM45xCAELLr/view?usp=share_link
Try pinching to zoom on the image. After a few goes at it, you'll likely find that one time it will scroll instead of pinching to zoom. It might take up to a dozen pinches to experience this issue.
What I've Tried
Making the magnification gesture a high priority gesture.
Having only one page in the paging view controller.
Subclassing UIScrollView and conforming to the UIGestureRecognizerDelegate in that subclass, as explained here: https://stackoverflow.com/a/51070947/12218938
Using the iOS 17 ScrollView instead. Unfortunately it has the same issue but even worse! It's possible that since this is a native SwiftUI view, people might have solutions to this, but from a brief search I couldn't find any.
If you set the data source to nil (which indicates that there are no other pages for the paging view controller to scroll to), it does work, but it's not a workable solution since the time you'd want to set the data source to nil is when the user pinches the screen, but you can't know when the user pinches the screen if the gesture doesn't work!
Other Ideas/Workarounds
We could have some "zoom" mode that temporarily cancels the ability to scroll while zooming. But this seems like not too nice/intuitive of a solution.
If there is no paging view that Apple provides which could be made compatible with a pinch-to-zoom gesture, it's possible we would have to make a completely custom paging view. But that would be a lot of work I presume, so it's probably not something we would have time for right now.
Hi guys, I’m making a simple note taking app and I want to support markdown functionality. I have tried to find libraries and many other GitHub repos but some of them are slow and some of them are very hard to implement and not very customizable.
In WWDC 22 apple also made a markdown to html document app and I also looked at that code and it was awesome. It was fast and reliable (Apple btw).
But the only problem I am facing is that the markdown text is on the left side and the output format is on the right in the form of html. I don’t want that I want both in the same line. In bear notes and things 3 you can write in markdown and you can see that it is converting in the same line. I have also attached example videos. So, I have markdown parser by apple but the only thing in the way is that it is converting it into a html document. Please help me with this. Also please look into the things 3 video they have also completely customized the text attributes selection menu. By default with UITextView we can only enable text attributes and it shows like this.
By clicking more we get the complete formatting menu but not the slider menu which is more convenient. Please also help me this. I don’t know if I can provide apple file but it is from wwdc 22 supporting desktop class interaction
Xcode 16.2
Swift 6
macOS Sequoia 15.1
SwiftUI
I am a beginner.
If I understand we can add buttons to the default Menu Bar but not delete them. Am I right? If you do not need most of the buttons, how do you solve that?
I can add a button:
import SwiftUI
@main
struct NouMenuProvesApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.commands {
CommandMenu("Custom") {
Button("Custom Action") {
print("Custom Action performed")
}
}
}
}
}
Can I delete a Menu Button or create a new simpler Menu Bar?
I don't know why, but for my MacCatalyst target, I have to make my view controller Y orgin 36 and the subtract the view height by 36 points, or the view is clipped.
The following works in my main UIViewController, but feels super hacky. I'd feel better if I understood the issue and addressed it properly.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
#if targetEnvironment(macCatalyst)
if view.frame.origin.y < 1 {
let f = UIApplication.shared.sceneBounds
let newFrame = CGRect(x: 0.0, y: 36, width: f.size.width, height: f.size.height - 36)
self.view.frame = newFrame
}
#endif
}
My guess is it starts the view under the title bar, but I have these set in the view controller:
self.extendedLayoutIncludesOpaqueBars = false
self.edgesForExtendedLayout = []
Hi.
I know to know which window gets hardware keyboard events (such as shortcut key) currently on iPad.
Until iPadOS 15.0, UIApplication.shared.keyWindow, which was deprecated on iPadOS 13.0 and didBecomeKeyNotification/didResignKeyNotification.
But after iPadOS 15.0, a keyWindow is managed by UIScene, not by UIApplication.
Each scene of my app always has just one window.
For my purpose, checking deprecated UIApplication.shared.keyWindow is still effective but didBecomeKeyNotification and didResignKeyNotification don't work because they are fired when a change happens only inside the scene.
So my questions are,
What is the new alternative of UIApplication.shared.keyWindow?
I know a wrong hack like
UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.first?.windows.filter { $0.isKeyWindow }.first
does not work since the order of connectedScenes is not related with getting hardware keyboard events.
What are the new alternatives of didBecomeKeyNotification/didResignKeyNotification which work on inter-scene?
The second question is more crucial.
Because about the first question, I can still use deprecated UIApplication.shared.keyWindow.
Thanks.
Hi there, I'm currently using UIHostingController to display swift charts in uikit. The problem im facing is that the UIHostingController isn't outputting the intended theme. When the simulator/phone is on dark mode the view is still in light mode. Iv'e tried to force the view to use dark mode with:
.environment(\.colorScheme, .dark)
But it doesn't seem to help. Here's how I implement the UIHostingController to my view:
let controller = UIHostingController(rootView: StatVC())
controller.view.translatesAutoresizingMaksIntoConstraints = false
addChild(controller)
controller.didMove(toParent: self)
view.addSubview(controller.view)
where StatVC() is the swiftui view which contains the swift chart.
Hello, since I'm using SwiftUI and some interface should be optimized for different devices(like iPad and iPhone), so I'm curious that what device would be used to run the App? Is it iPad or iPhone?
And could I use SDKs like SiriKit?
Hi,
I am developing a new SwiftUI app. Running under OSX, I see very high cpu usage (I am generating lots of gpu based updates which shouldn't affect the cpu).
I have used the profiler to ensure my swift property updates are minimal, yet the cpu usage is high coming from SwiftUI.
It seems the high cpu usage is coming from NSAppearance, specifically, CUICopyMeasurements - for a single button??? But the swift updates don't show any buttons being updating
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hi everyone,
I believe this should be a simple and expected default behavior in a real-world app, but I’m unable to make it work:
1. I have a View (a screen/page in this case) that calls an endpoint using async/await.
2. If the endpoint hasn’t finished, but I navigate forward to a DetailView, I want the endpoint to continue fetching data (i.e., inside the @StateObject ViewModel that the View owns). This way, when I go back, the View will have refreshed with the fetched data once it completes.
3. If the endpoint hasn’t finished and I navigate back to the previous screen, I want it to be canceled, and the @StateObject ViewModel should be deinitialized.
I can achieve 1 and 3 using the .task modifier, since it automatically cancels the asynchronous task when the view disappears:
view
.task { await vm.getData() }
I can achieve 1 and 2 using a structured Task in the View (or in the ViewModel, its the same behavior), for example:
.onFirstAppearOnly {
Task { away vm.getData() }
}
onFirstAppearOnly is a custom modifier that I have for calling onAppear only once in view lifecycle. Just to clarify, dont think that part is important for the purpose of the example
But the question is: How can I achieve all three behaviors? Is this really such an unusual requirement?
My minimum deployment target is iOS 15, and I’m using NavigationView + NavigationLink. However, I have also tried using NavigationStack + NavigationPath and still couldn’t get it to work.
Any help would be much appreciated.
Thank you, folks!
I have a Form with a custom TextField which uses a custom Text().
When I use .alignmentGuide on the Text() it seems the origin reference point varies with the length of, but not by the length of, the TextField label String. This is a problem when in a Form. My workaround has been to not use a TextField label but enclose the each TextField in a LabeledContent and then I can set the width of the label and align off of that.
How does Form cause TextField to set it's width and why if using .alignmentGuide on Text() does the TextField label length even matter?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am having issues with my app on visionOS. It works fine on iOS. The app is presenting a ImagePicker, I had tried converting to PhotoPicker and the behavior did not change.
The relevant code is in the EditGreetingCardView -
//
// Created by Michael Rowe on 1/2/24.
//
import AVKit
import SwiftData
import SwiftUI
struct EditGreetingCardView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Query(sort: \EventType.eventName) private var events: [EventType]
var greetingCard: GreetingCard?
private var editorTitle: String { greetingCard == nil ? "Add Greeting Card" : "Edit Greeting Card" }
@State var frontImageSelected: Image? = Image("frontImage")
@State var sourceType: UIImagePickerController.SourceType = .photoLibrary
@State var frontPhoto = false
@State var captureFrontImage = false
var eventTypePassed: EventType?
@State private var eventType: EventType?
@State private var cardName = ""
@State private var cardManufacturer = ""
@State private var cardURL = ""
@State private var cardUIImage: UIImage?
@State private var cameraNotAuthorized = false
@State private var isCameraPresented = false
@State private var newEvent = false
@AppStorage("walkthrough") var walkthrough = 1
init(eventTypePassed: EventType?) {
if let eventTypePassed {
_eventType = .init(initialValue: eventTypePassed)
}
}
init(greetingCard: GreetingCard?) {
self.greetingCard = greetingCard
_eventType = .init(initialValue: greetingCard?.eventType)
}
var body: some View {
NavigationStack {
Form {
Section("Occasion") {
Picker("Select Occasion", selection: $eventType) {
Text("Unknown Occasion")
.tag(Optional<EventType>.none) //basically added empty tag and it solve the case
if events.isEmpty == false {
Divider()
ForEach(events) { event in
Text(event.eventName)
.tag(Optional(event))
}
}
}
}
.foregroundColor(Color("AccentColor"))
Section("Card details") {
}
.foregroundColor(Color("AccentColor"))
Section("Card Image") {
HStack(alignment: .center){
Spacer()
ZStack {
Image(uiImage: cardUIImage ?? UIImage(named: "frontImage")!)
.resizable()
.aspectRatio(contentMode: .fit)
.shadow(radius: 10 )
Image(systemName: "camera.fill")
.foregroundColor(.white)
.font(.largeTitle)
.shadow(radius: 10)
.frame(width: 200)
.onTapGesture { self.frontPhoto = true }
.actionSheet(isPresented: $frontPhoto) { () -> ActionSheet in
#if !os(visionOS)
ActionSheet(
title: Text("Choose mode"),
message: Text("Select one."),
buttons: [
ActionSheet.Button.default(Text("Camera"), action: {
checkCameraAuthorization()
self.captureFrontImage.toggle()
self.sourceType = .camera
}),
ActionSheet.Button.default(Text("Photo Library"), action: {
self.captureFrontImage.toggle()
self.sourceType = .photoLibrary
}),
ActionSheet.Button.cancel()
]
)
#else
ActionSheet(
title: Text("Choose mode"),
message: Text("Select one."),
buttons: [
ActionSheet.Button.default(Text("Photo Library"), action: {
self.captureFrontImage.toggle()
self.sourceType = .photoLibrary }),
ActionSheet.Button.cancel()
]
)
#endif
}
.fullScreenCover(isPresented: $captureFrontImage) {
#if !os(visionOS)
ImagePicker(
sourceType: sourceType,
image: $frontImageSelected)
.interactiveDismissDisabled(true)
#else
ImagePicker(
image: $frontImageSelected)
.interactiveDismissDisabled(true)
#endif
}
}
.frame(width: 250, height: 250)
Spacer()
}
}
}
.alert(isPresented: $cameraNotAuthorized) {
Alert(
title: Text("Unable to access the Camera"),
message: Text("To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app."),
primaryButton: .default(Text("Settings")) {
openSettings()
}
,
secondaryButton: .cancel()
)
}
.toolbar {
}
.onAppear {
}
.onChange(of: frontImageSelected) { oldValue, newValue in
cardUIImage = newValue?.asUIImage()
}
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am creating an application that uses VNDetectBarcodesRequest to read QR codes from images and adjust the image orientation to match that of the QR code finder pattern.
The QR code was successfully read, and the coordinates of the QR code were obtained.Upon checking the obtained topLeft, topRight, and bottomLeft coordinates, they always seem to match the topLeft, topRight, and bottomLeft coordinates of the finder pattern.
Is it specified that the coordinates of topLeft, topRight, and bottomLeft obtained with VNDetectBarcodesRequest match the topLeft, topRight, and bottomLeft of the finder pattern? Or do they just happen to match?
I would appreciate it if you could tell me if the matching of coordinates is a specification.
Thank you for your help.
Before ios18, when two fingers are switched to single fingers, the printing scale value will not change. When switching to two fingers again, the pinch and zoom printing scale will change. The same operation is performed after ios18, and two fingers are switched to single fingers. Switch back to two fingers, and the scale printing will not change.
code here:
- (void)pinchGesture:(UIPinchGestureRecognizer *)recognizer {
NSSet <UIEvent*> *events = [recognizer valueForKey:@"_activeEvents"];
UIEvent *event = [events anyObject];
if (recognizer.state == UIGestureRecognizerStateBegan) {
NSLog(@"---- begin finger count: %d scale: %f",event.allTouches.count,recognizer.scale);
recognizer.scale = 1.0;
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
NSLog(@"---- change finger count: %d scale: %f",event.allTouches.count,recognizer.scale);
// recognizer.scale = 1.0;
}
log image for iOS 17.7
log image for ios18.0.2
1.APPStore Arraignment passed. Not yet released. The diagnostic link configuration is not available.
Firstly,We filled in the configuration of the corresponding domain name, and the verification was successful.
My AASA file is configured correctly (general deep links work with it, as well as some app clip URLs) and is also configured for app clips.
"applinks": {
"apps": [],
"details": [
{
"appID": "xxx.com.xx.easyshare",
"paths": [
"*"
]
},
{
"appID": "xxx.com.xx.easyshareExport",
"paths": [
"*"
]
}
]
},
"appclips": {
"apps": [
"xxx.com.xx.easyshare.Clip"
]
}
}
Well,I used https://es.xx.com/send or https://es.xx.com to get diagnostic information is wrong
My TestFight config is ok
Another problem is that using NFT jumps directly to Safire.