Post

Replies

Boosts

Views

Activity

Slide over UIViews To Select
I have a bar graph which I’ve created. Each bar is a UIView. You can tap on each bar and it’ll display its value in a label above. How make it so that you could just slide/pan over the bars and it would select whichever bar your finger is over at that moment.
1
0
454
Jul ’21
How to update Tabular Model on Device?
I'm trying to create a model to predict a user's screen time based on a variety of factors. I created a model in Create ML which works for me but this obviously wouldn't work for anyone else. How do I basically create a new model in the app using a new csv table and keep on updating that model as the user records more data and updates the csv file? This is possible in playgrounds since I can use the CreateML framework but this isn't available on iOS.
0
0
531
May ’21
Can't save Updated ML Model - gives nil error
When I try update my model I just get a nil error here.     private static func saveUpdatedModel(_ updateContext: MLUpdateContext) {         let updatedModel = updateContext.model         let fileManager = FileManager.default         do {             // Create a directory for the updated model.             try fileManager.createDirectory(at: tempUpdatedModelURL,                                             withIntermediateDirectories: true,                                             attributes: nil)                          // Save the updated model to temporary filename.             try updatedModel.write(to: tempUpdatedModelURL)             print("tempUpdatedModelURL - \(tempUpdatedModelURL)")                          // Replace any previously updated model with this one.             _ = try fileManager.replaceItemAt(updatedModelURL,                                               withItemAt: tempUpdatedModelURL)                          print("Updated model saved to:\n\t\(updatedModelURL)")         } catch let error {             print("Could not save updated model to the file system: \(error)")             return         }     } It creates the update task fine and the printed URL below is correct. extension UpdatableDrawingClassifier {     /// Creates an update model from a given model URL and training data.     ///     /// - Parameters:     ///     - url: The location of the model the Update Task will update.     ///     - trainingData: The training data the Update Task uses to update the model.     ///     - completionHandler: A closure the Update Task calls when it finishes updating the model.     /// - Tag: CreateUpdateTask     static func updateModel(at url: URL,                             with trainingData: MLBatchProvider,                             completionHandler: @escaping (MLUpdateContext) - Void) {                  // Create an Update Task.         guard let updateTask = try? MLUpdateTask(forModelAt: url,                                            trainingData: trainingData,                                            configuration: nil,                                            completionHandler: completionHandler)                      else {                 print("Could't create an MLUpdateTask.")                 return         }                  updateTask.resume()         print("Updating Model - updateTask.resume()")         print("URL - \(url)")     } }
0
0
688
Apr ’21
Keep getting nil when strung to add Drawing to Drawing Set
When ever I tap the sumitBtn to train the model, I get an error for exampleDrawings.addDrawing(drawing) it is getting the drawing as an image properly so I'm not sure why its getting nil there. struct ExampleDrawingSet {     /// The desired number of drawings to update the model     private let requiredDrawingCount = 3     /// Collection of the training drawings     private var trainingDrawings = [UserDrawing]()     /// The emoji or sticker that the model should predict when passed similar images     //let emoji: Character     let key = "Test Key"     /// A Boolean that indicates whether the instance has all the required drawings.     var isReadyForTraining: Bool { trainingDrawings.count == requiredDrawingCount }     var count: Int {             trainingDrawings.count         }     /*     init(for emoji: Character) {         self.emoji = emoji     }*/    /// Creates a batch provider of training data given the contents of `trainingDrawings`.    /// - Tag: DrawingBatchProvider     var featureBatchProvider: MLBatchProvider {         var featureProviders = [MLFeatureProvider]()         let inputName = "drawing"         let outputName = "label"         for drawing in trainingDrawings {             let inputValue = drawing.featureValue             let outputValue = MLFeatureValue(string: key)             //let outputValue = MLFeatureValue(string: String(emoji))             let dataPointFeatures: [String: MLFeatureValue] = [inputName: inputValue,                                                                outputName: outputValue]                          if let provider = try? MLDictionaryFeatureProvider(dictionary: dataPointFeatures) {                 featureProviders.append(provider)             }         }        return MLArrayBatchProvider(array: featureProviders)    }     /// Adds a drawing to the private array, but only if the type requires more.     mutating func addDrawing(_ drawing: UserDrawing) {         if trainingDrawings.count requiredDrawingCount {             trainingDrawings.append(drawing)         }     } } class Page6MachinLearning: UIViewController, PKCanvasViewDelegate {     @IBOutlet var canvasView: PKCanvasView!     @IBOutlet var submitBtn: UIButton!     var submitWorkItem: DispatchWorkItem?     var exampleDrawings: ExampleDrawingSet!     var drawingCount = Int()      override func viewDidLoad() {         super.viewDidLoad()         configureCanvasView()     }     @IBAction func submitBtn(_ sender: Any) {         print("User tapped \"Done\"; kicking off model update...")         submitDrawing(canvasView: canvasView)         drawingCount+=1         print(drawingCount)         if drawingCount == 3 {         // Convert the drawings into a batch provider as the update input.         let drawingTrainingData = exampleDrawings.featureBatchProvider         // Update the Drawing Classifier with the drawings.         DispatchQueue.global(qos: .userInitiated).async {             ModelUpdater.updateWith(trainingData: drawingTrainingData) {                 DispatchQueue.main.async { self.dismiss(animated: true, completion: nil) }             }         }         } // End If     }        /// Configures the `PKCanvasView`     func configureCanvasView() {         canvasView.backgroundColor = .clear         canvasView.isOpaque = false         canvasView.tool = PKInkingTool(.pen, color: .white, width: 20)         canvasView.delegate = self         canvasView.allowsFingerDrawing = true     }     // MARK: - PKCanvasViewDelegate     func canvasViewDidBeginUsingTool(_ canvasView: PKCanvasView) {         // Cancel the submission of the previous drawing when a user begins drawing         // This lets the user draw another stroke without a time limit of 0.5 seconds         submitWorkItem?.cancel()     }     func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {         let drawingRect = canvasView.drawing.bounds         guard drawingRect.size != .zero else {             return         }         // Check if the user is crossing out previous stickers         let intersectingViews = canvasView.subviews             .compactMap { $0 as? UILabel }             .filter { $0.frame.intersects(drawingRect) }         guard intersectingViews.isEmpty else {             // If the current drawing intersects with existing stickers,             // remove those stickers             intersectingViews.forEach { $0.removeFromSuperview() }             canvasView.drawing = PKDrawing()             return         }         submitWorkItem = DispatchWorkItem { self.submitDrawing(canvasView: canvasView) }         DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 5, execute: submitWorkItem!)     }     func submitDrawing(canvasView: PKCanvasView) {         // Get the rectangle containing the drawing         let drawingRect = canvasView.drawing.bounds.containingSquare         // Turn the drawing into an image         // Because this image may be displayed at a larger scale in the training view,         // a scale of 2.0 is used for smooth rendering.         let image = canvasView.drawing.image(from: drawingRect, scale: UIScreen.main.scale * 2.0)         // Store the white tinted version and the rectangle in a drawing object         let drawing = UserDrawing(image: image.cgImage!, rect: drawingRect)         didProduce(drawing: drawing, sender: self)         DispatchQueue.main.async {             canvasView.drawing = PKDrawing()         }     } } extension Page6MachinLearning: DrawingDelegate {     func didProduce(drawing: UserDrawing, sender: Any?) {         DispatchQueue.main.async { self.addDrawing(drawing) }     }     func addDrawing(_ drawing: UserDrawing) {         print("drawing - \(drawing)")         exampleDrawings.addDrawing(drawing) //Error here     } }
3
0
866
Apr ’21
UIView Animation won't Loop
I've got a view where I need the animation to repeat with a completion handler and update labels. The animation only runs once and then it doesn't repeat.     let sums = ["add(5, 7)", "mult(6, 20)", "div(15, 3)", "mult(2, 1)"]     let answers = [12, 120, 5, 2]     func sumAnimation() {         for i in 0...sums.count-1 {             inputLbl.text = sums[i]             inputLbl.frame = CGRect(x: 0, y: 13, width: Int(inputLbl.frame.width), height: Int(inputLbl.frame.height)) // move to 340                          UIView.animate(withDuration: 3 - clockSpeed/2) {                 self.inputLbl.transform = CGAffineTransform(translationX: 700, y: 0)             } completion: { (true) in                 self.outputLbl.text = "ansr(\(self.answers[i]))"             } // End Completion         } // End Loop     } // End Func
2
0
1.8k
Apr ’21