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.
Post
Replies
Boosts
Views
Activity
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)
}
}
}
}
}`
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] = []
}
}
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?
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.
Does anyone know how to include the Options button and functionality in the UIActivityViewController, that can be seen when sharing a photo for example: https://ibb.co/cc56qtYWe want our users to be able to decide what files to share in that Options dialog.
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)