I found a solution, but it implies subclassing the subviews for which the "realSize" is needed : in the method layoutSubviews of a subclassed UIView, the size is correct
I tried all: ViewDidLyoutSubviews, viewWillLayoutSubviews and ViewWillTransaition
there is two problems in viewDidLayoutSubviews:
When the controller appears, viewDidLayoutSubviews is called twice. The sizes of the subviews are not always correct in the first call, it became correct in the second call
when the iphone change its orientation, viewDidLayoutSubviews is called again, but the sizes of the subviews are identical, like if constraints will be applied later. for instance if the width of a subview is 246 in portrait and 278 in landscape : when the controller is in portrait, size is effectively 246. When it turn's to landscape, size is still 246 and when it turns back to portrait, size is 278
Your ,last comment gave me an idea Claude. if I have 2 differnt storyboard for my UITableViewCell, I can write this in the
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
of the uiViewController:
let cell : UITableViewCell
if view.traitCollection.className == "RR" {
if UIScreen.main.bounds.size.width < UIScreen.main.bounds.size.height{
cell = table.getCell(indexPath) as! class1
} else {
cell = table.getCell(indexPath) as! class2
}
}
where class2 is a descendant of class1
Class2 if a descendant of class1, and can have other UIView installed and as class1 and class2 don't have the same storyboard, the constraints wh-ill not be the same.
I have to precise that I wrote the following extension;
extension UITraitCollection {
public var className: String {
get {
return (horizontalSizeClass == .compact ? "C" : "R") + (verticalSizeClass == .compact ? "C" : "R")
}
}
}
Yes, I thought of something like this
But it means that I have to make constraints programatically for class RR, without capable of using functionallities of IB
Thank's Claude
I'm very sorry, but it seems that file:///Users/patricerapaport/Library/Containers/PR.medical/Data/Documents/ links to file:///Users/patricerapaport/Library/Containers/medical/Data/Documents/
because I wrote this:
let dialogURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
print(dialogURL)
var isDir = ObjCBool(false)
let exists = FileManager.default.fileExists(atPath: dialogURL!.path, isDirectory: &isDir)
print(exists)
and the result for print(exists) is true
(I don't know how to close the thread)
I thought it was something like that, but it means that if I don't correct the size in size inspector, I will always have the problem.
IB can deserialise values by reading XIB file, but there is no way to change these values by program and serialise them back.
The case I presented was very simple, but what if I put constraints by program? In this case I don't know the exact size of MyView and if I have multiple subclassed controls, it becomes very confuse in the view of Interface Builder.
Post not yet marked as solved
I wanted to simplify my problem, that's why I put the constraints in the subclass (class Container)
It is exactly the same if I put the constraints in the code of the ViewController
I think the problem is that Interface Builder doesn't apply constraints.
If I add the following method:
func setupIBConstraints() {
if (superview?.frame.size.width)! < (superview?.frame.size.height)! {
label.text = "setupIBConstraints(.CR \(superview?.frame.size.width)"
label.sizeToFit()
self.layer.frame = CGRect(x: 30, y: 100, width: (superview?.frame.size.width ?? 0)-60, height: (superview?.frame.size.height ?? 0)-300)
} else {
label.text = "setupIBConstraints(.CC ou .RC \(superview?.frame.size.width)"
label.sizeToFit()
self.layer.frame = CGRect(x: 20, y: 50, width: (superview?.frame.size.width ?? 0)-100, height: (superview?.frame.size.height ?? 0)-100)
}
}
and in method layoutSubviews() I replace setupConstraints(theOrientation) by
#if TARGET_INTERFACE_BUILDER
setupIBConstraints()
#else
setupConstraints(theOrientation)
#endif
I can see a correct result in Interface Builder
it proves that code is well executed by Interface Builder
change of frame is OK for IB but it doesn't apply constraints
I would reformulate my question: how to apply programmatic constraints in IB
Of course, I can write constraints in IB but I thought it was possible by program and see the results in IB
The point is that if the UIElements of my cell have layout inferred, I can see in IB all the elements placed correctly. But when the program is running, none of the constrains applied.
In the other case, if the UIElements have layout autoresizing make, if I change from portrait to landscape the elements are not placed correctly
Yes of course I set variations of constraints
But I don't see the result in Interface Builder.
Imagine just a UItableViewCell.
If I made variations, in portrait mode the width will be for instance 400, and in Landscape Mode the width will be 800.
But there is no visual in IB. If I go in portrait mode, or in landscape mode, the visual doesn't change, even if I put the width in constraint
I'm very ashamed
It effectively was an internal error.
The code was never called
Please excuse me, all of you, for disturbing
I confirm the variable aController is not nil so displayAlert is called
All is my faultThe lesson of it is we have to think much more harder before making a postMy subclassed control, in the override function becomeFirstResponder didn't called super.becomeFirstResponder (the function of the NSTextField). As a result, currentEditor() of the control returned nil.When calling super.becomeFirstResponder, the function currentEditor returns the desired editor.Sorry about all this
when the instructionvar fieldEditor = ctrlRch.currentEditor()is executed, fieldEditor is nil
ctrlRch.setSelectedRange = NSMakeRange(ctrlRch!.stringValue.count-1, 1)gives:Value of type 'NSTextField' has no member 'setSelectedRange'