Post

Replies

Boosts

Views

Activity

How to add axis labels with DGCharts in Swift?
We are updating our code to work with DGCharts v.4.0 (previously Charts) and our previously working solution for adding labels for the x and y axis (see below) is now no longer working, as "ChartUtils" cannot be found. Does anyone know how this can be achieved with DGCharts? private extension LineChartYAxisRenderer { func renderTitle(title: String, inContext context: CGContext, x: CGFloat) { var foregroundColor = UIColor.darkGray foregroundColor = UIColor.secondaryLabel let attributes: [NSAttributedString.Key: Any] = [ .font: self.axis.labelFont, .foregroundColor: foregroundColor ] // Determine the chart title's y-position. let titleSize = title.size(withAttributes: attributes) let verticalTitleSize = CGSize(width: titleSize.height, height: titleSize.width) let point = CGPoint(x: x, y: ((viewPortHandler.chartHeight - verticalTitleSize.height) / 2)-30) // Render the chart title. ChartUtils.drawText(context: context, text: title, point: point, attributes: attributes, anchor: .zero, angleRadians: .pi / -2) Does anyone know how this can be achieved with DGCharts? We're using Swift5.
0
0
457
Nov ’23
Swipe TabView mapped to scrollable HStack with images
Hi! I'm trying to create a view where the user should be able to select images from a recorded video as in the attached example image. There should be a scrollable HStack, showing every 20th frame from the recorded video, with a vertical line (horizontally positioned at the middle of the screen) marking the current frame. The current frame should be shown as an enlarged image above the thumbnail images. The user should be able to swipe the enlarged image to go between frames, i.e. scroll one frame position back or forth (and also be able to change frame by dragging/scrolling the HStack, but that will be a later problem). I have managed to generate frames from a recorded video and set up a TabView to present the current frame (enlarged image) with swiping functionality, and a ScrollView below to present the thumbnails. But I can't figure out how to get the scrollTo-funcitonality to work. Right know the scrolling positions are off (my invisible scroll to-elements do not line up correctly with the thumbnail images. I have attached my messy code of the scrollable HStack if that is of any help. Thankful for any tips! `struct ViewOffsetKey: PreferenceKey {     typealias Value = CGFloat     static var defaultValue = CGFloat.zero     static func reduce(value: inout Value, nextValue: () -> Value) {         value += nextValue()     } } struct ViewMinXKey: PreferenceKey {     typealias Value = CGFloat     static var defaultValue = CGFloat.zero     static func reduce(value: inout Value, nextValue: () -> Value) {         value += nextValue()     } } struct ViewMaxXKey: PreferenceKey {     typealias Value = CGFloat     static var defaultValue = CGFloat.zero     static func reduce(value: inout Value, nextValue: () -> Value) {         value += nextValue()     } } struct StackedPhotosView: View {     @EnvironmentObject var videoManager: VideoManager     @State var minX: CGFloat = 0.0     @State var maxX: CGFloat = 0.0          var body: some View {         GeometryReader { geometry in             ScrollViewReader { reader in                 ScrollView(.horizontal) {                             HStack(spacing: 0) {                                                                  // Rectangle to create an offset so that the thumbnail images start at the middle of the screen                                 Rectangle().frame(width:geometry.size.width/2, height: 70).foregroundColor(Color.clear)                                 ZStack {                                     HStack(spacing: 0) {                                                                                  // Show every 20th image                                         ForEach(Array(videoManager.frames.enumerated()), id: .1.id) { (index, item) in                                                                                          if index % 20 == 0 {                                                 Image(uiImage: item.image)                                                     .resizable()                                                     .border(.black, width: 1)                                                     .frame(height: 70)                                                     .aspectRatio(1.0, contentMode: .fit)                                                     .rotationEffect(.degrees(90))                                             }                                         }                                     }                                                                          if maxX > 0 {                                         // Create invisible "scroll to" elements with ids for every frame                                         HStack(spacing:0) {                                             ForEach(videoManager.frames.indices, id: .self) { i in                                                 Spacer()                                                     .id(i)                                                     .frame(width: Double((maxX-(geometry.size.width/2))/CGFloat(videoManager.frames.count)), height: 70)                                                     .foregroundColor(.red)                                                     .border(.black, width: 1)                                                     .opacity(0.5)                                             }                                         }                                     }                                 }                                                                  // Rectangle extending the HStack and making all images being able to pass the vertical blue line                                 Rectangle().frame(width:geometry.size.width/2, height: 70).foregroundColor(Color.clear)                             }                             .background(GeometryReader  {                                 Color.clear.preference(key: ViewOffsetKey.self,                                                        value: -$0.frame(in: .named("scroll")).origin.x) // Will be used later to change top image when drag-scrolling on the HStack                                 Color.clear.preference(key: ViewMinXKey.self,                                                        value: $0.frame(in: .local).minX)                                 Color.clear.preference(key: ViewMaxXKey.self,                                                        value: $0.frame(in: .local).maxX - geometry.size.width)                             })                 }                 .onChange(of: videoManager.currentFrameNr, perform: { index in                     withAnimation(.linear) {                         reader.scrollTo(index, anchor: .leading)                     }                 })                 .onPreferenceChange(ViewMinXKey.self) {                     minX = CGFloat($0)                 }                 .onPreferenceChange(ViewMaxXKey.self) {                     maxX = CGFloat($0)                 }             }                 }     } }`
0
0
1.1k
Feb ’23
Converting struct so it can be sent from watch to phone
I want to send struct data from my watchOS-app to my iOS-app using WatchConnectivity. As I have understood, you can only send property list objects, hence I must convert my struct somehow. I tried converting it into a NSDictionary, and also make it a Codable struct, but it doesn't work since I have properties that does not conform to the Codable prototocols. Any suggestions on how this can be solved in a good way?I'm using XCode Version 10.1 and Swift 4.2.Here is my struct:struct Storage { var acc: Acc struct Acc { var x: [Double] = [] var y: [Double] = [] var z: [Double] = [] } var gyro: Gyro struct Gyro { var x: [Double] = [] var y: [Double] = [] var z: [Double] = [] } var mag: Mag struct Mag { var x: [Double] = [] var y: [Double] = [] var z: [Double] = [] } var pulse: [Double] = [] var quaternion: Quaternion struct Quaternion { var w: [Double] = [] var x: [Double] = [] var y: [Double] = [] var z: [Double] = [] } }
3
0
1.8k
Mar ’19
Update intervals for startDeviceMotionUpdatesToQueue:withHandler:
I'm creating an app that uses CMDeviceMotion to collect device-motion updates from an iPhone and Apple Watch at an update interval set by the user (varying from 20 Hz to 100 Hz). When checking the timestamps generated for each CMDeviceMotion instance, I have seen that some set update intervals does not equal the true update interval, while some are very precise. For example, setting the update interval to 0.0167 s (60 Hz) and. 0.0125 s (80 Hz) results in true update intervals of 0.019 s and 0.015 s respectively, while at 40 Hz and 100 Hz, the true update interval is as expected. So at some update intervals, it seems to round up or down to an update interval or frequency that "works"?From the documentation, I understand that deviceMotionUpdateInterval is capped to minimum and maximum values, e.g. the maximum value is determined by the maximum frequency supported by the hardware. But what about in between? Does anyone know anything more about this?
2
0
840
Sep ’19
Collect sensor data in the background
I'm creating an app that uses CMDeviceMotion to collect gyroscope and accelerometer data from the watch and phone respectively. The data collection should be able to last continuously for about 10 minutes. Problem is, the collection stops whenever the screen goes black. What would be the best way to make sure the collection continues in sleep mode? Can I collect data from these sensors in a HKWorkoutSession?I'm using XCode version 10.2 and Swift 4.2.
4
1
7k
Mar ’19
Can't AirDrop more than one object type at the same time
I'm trying to share both a csv and a pdf file from my iPhone app (tried from both iPhone SE and iPhone X) to my Mac Pro 2018 using AirDrop from the UIActivityViewCointroller, but it fails. I read a post from 2016 in another forum stating the same issue with simultaneously sending multiple different object types with AirDrop.Anyone who knows if there's a workaround to fix this problem today or if it's still a restriciton in AirDrop?// Write to the temporary file. csvText.write(to: path, atomically: true, encoding: String.Encoding.utf8) DispatchQueue.main.async { let f = self.myEVAChartView.getChartImage(transparent: false)! let pdfCreator = PDFCreator(title: (self.title ?? "No title"), body: (self.note ?? "No notes"), image: f, contact: mail) let pdfData = pdfCreator.createReport() // Init Activity view controller. let activity = UIActivityViewController( activityItems: [path, pdfData], applicationActivities: nil ) //Show the Activity view controller. self.progressHUD.hide() activity.popoverPresentationController?.barButtonItem = sender activity.excludedActivityTypes = [.addToReadingList, .assignToContact, .copyToPasteboard, .markupAsPDF, .message, .openInIBooks, .postToFlickr, .postToTencentWeibo, .postToTwitter, .postToFacebook, .postToVimeo, .postToWeibo, .print, .saveToCameraRoll] self.present(activity, animated: true, completion: nil)
5
0
6.4k
May ’20