Post

Replies

Boosts

Views

Activity

swift and AppDirectory
I develop an App in macos, and I need to access the documentDirectory: let dialogURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first I get: file:///Users//Library/Containers/<*******.appName>/Data/Documents But in the Library/Containers directory I don't have the <*******.appDirectory> (in my case "PR.medical") but (in my case "medical") of course, it would be possible to hard code the name of the desired directory, but if in the future apple change anything, my app will not work properly. Am I missing something?
4
0
864
Nov ’21
Interface Builder and subclassed UIView
I test a very simple thing: I have a Subclassed UIView as follow: @IBDesignable class myView: UIView {          override public init(frame: CGRect) {         super.init(frame: frame)     }     required public init?(coder aDecoder: NSCoder) {         super.init(coder: aDecoder)     }       override open func layoutSubviews() {         super.layoutSubviews()         layer.frame.size.height = 50         layer.borderWidth = 1         layer.borderColor = UIColor.green.cgColor     } } To install this component in Interface Builder, I add an UIView and I change the class name in the Inspector. When I add the UIView, the height of this view is 128. I suppose it is a default value of IB. But I want this height to be 50. When I change the name of the class in the IB inspector, the view is correctly drawn, white a height of 50, but when I select it, the size of the selection is the size of a default UIView Is there a mean to correct this?
3
0
689
Sep ’21
programmatic constraints and Interface Builder
I subclassed an UIView that is supposed to create it's owned constraints: @IBDesignable class MyCtrl: UIView { var label: UITextField! var _internalLayout = false public override init(frame: CGRect) { super.init(frame: frame) _init() } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) _init() } open override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() self._init() self.setNeedsDisplay() } func _init() { label = UITextField() addSubview(label) super.backgroundColor = .cyan #if TARGET_INTERFACE_BUILDER translatesAutoresizingMaskIntoConstraints = true #else translatesAutoresizingMaskIntoConstraints = false #endif } override public func layoutSubviews() { if _internalLayout { _internalLayout = false return } let theOrientation = orientation setupConstraints(theOrientation) super.layoutSubviews() } func setupConstraints(_ orientation: IosTraitClass) { _internalLayout = true superview?.removeConstraints(superview!.constraints) if orientation == .CR { label.text = "setupConstraints(.CR \(superview?.frame.size.width)" label.sizeToFit() superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: superview , attribute: .leading , multiplier: 1, constant: 30)) superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: superview, attribute: .top, multiplier: 1, constant: 100)) superview?.addConstraint( NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: .none, attribute: .notAnAttribute, multiplier: 1, constant: (superview?.frame.size.width ?? 0)-60)) superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: .none, attribute: .notAnAttribute, multiplier: 1, constant: (superview?.frame.size.height ?? 0)-300)) } else if orientation == .RC || orientation == .CC { label.text = "setupConstraints(.CC ou .RC \(superview?.frame.size.width)" label.sizeToFit() superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: superview, attribute: .trailing, multiplier: 1, constant: -50)) superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: superview, attribute: .top, multiplier: 1, constant: 50)) superview?.addConstraint( NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: .none, attribute: .notAnAttribute, multiplier: 1, constant: (superview?.frame.size.width ?? 0)-100)) superview?.addConstraint(NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: .none, attribute: .notAnAttribute, multiplier: 1, constant: (superview?.frame.size.height ?? 0)-100)) } } } In the method layoutSubviews of my component, I called orientation which is an extension of UIView: public var orientation: IosTraitClass { if UIScreen.main.traitCollection.horizontalSizeClass == .regular && UIScreen.main.traitCollection.verticalSizeClass == .compact { return .RC } else if UIScreen.main.traitCollection.horizontalSizeClass == .compact && UIScreen.main.traitCollection.verticalSizeClass == .regular { return .CR } else if UIScreen.main.traitCollection.horizontalSizeClass == .compact && UIScreen.main.traitCollection.verticalSizeClass == .compact { return .CC } else if UIScreen.main.traitCollection.horizontalSizeClass == .regular && UIScreen.main.traitCollection.verticalSizeClass == .regular { return .RR } else { return .none } } Finally I made a UIViewController: class ViewController: UIViewController { @IBOutlet weak var container: MyCtrl! override func viewDidLoad() { super.viewDidLoad() setupConstraints() } func setupConstraints() { container.setupConstraints(view.orientation) } func calculatedConstraints() -> [NSLayoutConstraint] { return []; var constraints = [NSLayoutConstraint]() container.removeConstraints(container.constraints) if view.orientation == .CR { //constraints.append(contentsOf: container.setSize(width: (view?.frame.size.width ?? 0)-60, height: (view?.frame.size.height ?? 0)-300)) } else { //constraints.append(contentsOf: container.setSize(width: (view?.frame.size.width ?? 0)-40, height: (view?.frame.size.height ?? 0)-100)) } return constraints } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { container.setupConstraints(view.orientation) super.viewWillTransition(to: size, with: coordinator) } } When I run my program the constraints are well applied in landscape or portrait mode. But when I look in the interface Builder, constraints are not applied, and I don't understand Why
2
0
949
Aug ’21
Changing orientation in UITableViewCell
In a IOS App, I have an UITableViewCell with is own Nib and I want this UITableViewCell to react to orientation (In fact I want also this UITableViewCell to react to device: IPhone and IPad) Suppose there are two labels in my UITableViewCell. In a portrait orientation, the second label is under the first one, in a Landscape orientation the two labels are on the same line. First I noticed that in interface builder, if the layout of all the elements are Autoresizing Mask (and not inferred) I'm unable to put a constraint on width and heigth of the UITableViewCell and it's contentView. Now I choose in IB: orientation Portrait, I click on Vary For Traits and I put the necessary constraints. After that, I do the same for orientation Landscape. Then, whatever the orientation is in IB, I only see my last choice (landscape). IB doesnt react to Portrait or landscape orientation. And it is the same when I run the App: I only see the landscape layout. Where is my mistake? Do I have to make differnt nib files for all devices variations?
6
0
1.7k
Dec ’20
UIAlertAction
In order to display alerts, I made a simple class: public protocol AlertDisplayer {     func displayAlert(with title: String, message: String, actions: [UIAlertAction]?, completion: (() -> Void)?) } extension AlertDisplayer where Self: UIViewController {     public func displayAlert(with title: String, message: String, actions: [UIAlertAction]? = nil, completion: (() -> Void)? = nil ) {         guard presentedViewController == nil else {             return         }         let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)         actions?.forEach { action in             alertController.addAction(action)         }         present(alertController, animated: true, completion: nil) //{     } } Now I make a class to this class, from another class, like this: func passwordForgot(navigation: UINavigationController, email: String?) {         let model = loginModel()         model.rappelpwd(controller: navigation.topViewController as! AlertDisplayer, email: email!) {             result in             if result.result! {                 let defaultAction = UIAlertAction(title: "OK", style: .default, handler: {                     action  in                     Swift.print("ok tapped")                     //presentControllerLogin()                 })                 let title = "Attention"                 let aController = navigation.topViewController as? AlertDisplayer                 if aController != nil {                     aController!.displayAlert(with: title , message: result.msg!, actions: [defaultAction], completion: nil)                 }             }         }     } Everyting is OK, but when I tap the OK button, the handler is never called
5
0
673
Nov ’20
currentEditor
I have a windowController with a NSTableView and a textfield which I use to search data in my tableViewIn the controller, I intercept the keydown event and if it is a character, I want to fill the textfield with this character and give the focus to the textfieldSo I write@objc override func myKeyDown(with event: NSEvent) -&gt; Bool { if ctrlRch != nil { window?.makeFirstResponder(ctrlRch) Swift.print("firstResponder is \(window?.firstResponder)") ctrlRch.stringValue = event.characters! var fieldEditor = ctrlRch.currentEditor() fieldEditor?.selectedRange = NSMakeRange(ctrlRch!.stringValue.count-1, 1) return true }But the caret (or the cursor) is not positionned in the textfieldWhat I missed?
9
0
1.2k
Apr ’20
Encoding to dictionary
I'm completely lost in encoding classes to DictionaryI have for instance the following classclass AdjectifsModel: BaseModel { var id: Int = 0 var idmot: Int = 0 var idtypemot: Int = 0 var idracine: Int = 0 var racine: String = "" var francais: String = "" var msingulier: String = "" var fsingulier: String = "" var mpluriel: String = "" var fpluriel: String = "" var commentaire: String = "" var erreur: Int = 0 var nbliens: Int = 0 enum CodingKeys: String, CodingKey { case id case idmot case idtypemot case idracine case racine case francais case msingulier case fsingulier case mpluriel case fpluriel case commentaire case erreur case nbliens } }No problem to encode it with the following code:required convenience init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.init() self.id = try container.decoder(Int.self, forKey: .id) self.idmot = try container.decoder(Int.self, forKey: .idmot) self.idtypemot = try container.decoder(Int.self, forKey: .idtypemot) self.idracine = try container.decoder(Int.self, forKey: .idracine) self.racine = try container.decoder(String.self, forKey: .racine) self.francais = try container.decoder(String.self, forKey: .francais) self.msingulier = try container.decoder(String.self, forKey: .msingulier) self.fsingulier = try container.decoder(String.self, forKey: .fsingulier) self.mpluriel = try container.decoder(String.self, forKey: .mpluriel) self.fpluriel = try container.decoder(String.self, forKey: .fpluriel) self.commentaire = try container.decoder(String.self, forKey: .commentaire) self.erreur = try container.decoder(Int.self, forKey: .erreur, defaut: 0) self.nbliens = try container.decoder(Int.self, forKey: .nbliens, defaut: 0) }But in order to save my class, I need to transform it in a Dictionary [String: String] and I don't kown how to do itI found on the internet the following code:class DictionaryEncoder { private let encoder = JSONEncoder() var dateEncodingStrategy: JSONEncoder.DateEncodingStrategy { set { encoder.dateEncodingStrategy = newValue } get { return encoder.dateEncodingStrategy } } var dataEncodingStrategy: JSONEncoder.DataEncodingStrategy { set { encoder.dataEncodingStrategy = newValue } get { return encoder.dataEncodingStrategy } } var nonConformingFloatEncodingStrategy: JSONEncoder.NonConformingFloatEncodingStrategy { set { encoder.nonConformingFloatEncodingStrategy = newValue } get { return encoder.nonConformingFloatEncodingStrategy } } var keyEncodingStrategy: JSONEncoder.KeyEncodingStrategy { set { encoder.keyEncodingStrategy = newValue } get { return encoder.keyEncodingStrategy } } func encode(_ value: T) throws -&gt; [String: Any] where T : Encodable { let data = try encoder.encode(value) return try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any] } }I copy it (and I must admit that I don't undestand how it works).If my class contains only strings property, the following Code works:var params = try DictionaryEncoder().encode(self)but if the properties are mixed (Strings and Int) it doesn't work
4
0
2.4k
Mar ’20
Array function and generic types
I'm complety lost with Generic typesIn a class, I've declare an array, like this:class ResponseListl: Decodable { var moderators: [T] }this intends to get differnt values of T thru an internet connection.No problem to fill the array in a first time, but if I want to grow this array thru a second connection, I try to make this:moderators.append (data) (data is of type T) the compiler returns me the error:Cannot invoke 'append' with an argument list of type '([T])'What is wrong with this?
5
0
685
Feb ’20
NSWiewController
I'm developing an application with a NSSplitView in the main NSWindowController which is organized like that:a menu on the left panel, which contains an outlineView with many choices and a detailView on the right panel which corresponds to the item choosen in the left panel.In the main NSWindowController, I have a toolbar with Buttons (that's the important point)Then I click on an item in the left panel, I have the following action:func outlineViewSelectionDidChange(_ notification: Notification) { let outline = notification.object as! NSOutlineView let item = outline.item(atRow: outline.selectedRow) if item is MenuSocietes { if vc != nil { splitView.removeArrangedSubview((splitView?.subviews[1])!) vc = nil } vc = societesController() contentViewController?.presentAsModalWindow(vc) if splitView.subviews.count &gt; 1 { splitView.removeArrangedSubview((splitView?.subviews[1])!) } splitView.addSubview(vc.view) } if item is MenuImmeuble { if vc != nil { splitView.removeArrangedSubview((splitView?.subviews[1])!) vc = nil } vc = immeubleController((item as! MenuImmeuble).id) contentViewController?.presentAsModalWindow(vc) if splitView.subviews.count &gt; 1 { splitView.removeArrangedSubview((splitView?.subviews[1])!) } splitView.addSubview(vc.view) } else { if vc != nil { splitView.removeArrangedSubview((splitView?.subviews[1])!) vc = nil } } }Of course this is just a example (a little dirty, I know).societesController and immeubleController are NSViewControllers.Now I want my detailView (in the above code, societesController or immeubleController) to interact with the NSToolbar of the main NSWindowController.It would be easy to pass this toolbar as a parameter in the init code of my details NSViewController, but I'm not sure it's the finest way.I try to find, in my viewControllers (societesController and immeubleController) the ancestor, doing something like this:var _parent = presentingViewController while _parent != nil { Swift.print(_parent?.className) _parent = _parent!.parent }the first line return nil as _parent. Am I missing something?
3
0
569
Jan ’20
Swift UI and choice in a NavigationView
I'm discovering SwiftUI, thinking that it is the future for developping Applications.the first thing (I'm sure it is very simple) I have difficulties is making a choice in a dynamic List.In a classic Swift I make it like thisIn my menuViewController, I have these declarations:private var choix = ["Adjectifs", "Adverbes", "Noms", "Verbes", "Prépositions", "Expressions", "Phrases", "Racines", "Quizz"]//, "test"] private var actions = [adjectifsViewController.self, adverbesViewController.self, nomsViewController.self, verbesViewController.self, prepositionsViewController.self, expressionsViewController.self, phrasesViewController.self, associationsViewController.self, listerQuizzViewController.self] //, menu1ViewController.self]I draw a UITableView with choices ad when I click on a row of my tableView:func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if actions[indexPath.row] != "" { let aClass = actions[indexPath.row] let controller = aClass.loadFromNib() self.show(controller, sender: self) } }Now of course I want to write this in SwiftUIfirst I have a struct like this:struct IvritMenu: Identifiable { let id: Int let text: String let lien: click } enum click: Hashable { case adjectifs case adverbes case noms case verbes }then in the View, I write the variable:var menu = [ IvritMenu(id: 0, text: "Adjectifs", lien: .adjectifs), IvritMenu(id: 1, text: "Adverbes", lien: .adverbes), IvritMenu(id:2, text: "Noms", lien: .noms), IvritMenu(id:3, text: "Verbes", lien: .verbes)]and Finally:var body: some View { NavigationView { List(menu) { choix in ListeChoix(choix: choix) } .navigationBarTitle(Text("Ivrit")) } }now the difficult part (for me) is to write ListeChoixstruct ListeChoix: View { var choix: IvritMenu var body: some View { switch choix.lien { case .adjectifs: return Adjectifs() defaul make itt: return Adverbes() } } }this generate an error Function declares an opaque return type, but the return statements in its body do not have matching underlying typesI think this error is caused by the return which returns different types of View, but I don't know how to make it
5
0
1.8k
Dec ’19
NSButton doesn't work anymore
HiI update xcode to version 11.3 and my OS to Mojave (10.14.6)I had a macos app with NSButtons binded to a NSViewController@IBAction func Tester(_ sender: NSButton) { Swift.print("test activé") }(I made it very simple to isolate my problem)the function Tester of my viewController is never called and I can't find why
24
0
3.8k
Dec ’19