I am using Custom Cell in UITableView. And the basic model of the cell is as follows.
I would like to have the dashed line dynamically deformed according to the size of the Menu Name box in this cell. So I wrote the following code:
menuField.frame.size.width = getWidth(text: menuField.text!)
menuField.layoutIfNeeded()
dotLine.layoutIfNeeded()
func getWidth(text: String) -> CGFloat {
let txtField = UITextField(frame: .zero)
txtField.text = text
txtField.sizeToFit()
return txtField.frame.size.width
}
This worked very well. Only increase if only! If the Menu Name Frame is reduced below the currently set size, the size remains unchanged.
As you can see from the image above, I need to make not only the size of the dotted line increase but also the shrinkage. I do not know what my problem is. Please help me!
You don't need any of code you wrote, autolayout does this for you. Just set autolayout like this:
Dash is constraint with your value
- MenuTextField - Dotted line - Price -
I have solved my problem. First, I added the width dimension Constraints of the Menu Text Box and imported it into the IBOutlet variable.
#IBOutlet weak var menuWidth: NSLayoutConstraint!
And I changed the value of the variable according to the text length.
menuWidth.constant = getWidth(text: menuField.text!)
This method is not yet fully functional. But it works the way I want.
Also thanks to Robert Dresler who answered me :) Thanks!
Related
I'm building a simple NSGridView, and want to have a custom NSView as each element of the grid. Eventually, each NSView will be a xib based label (NSTextField) centered in the NSView.
The problem I am having is with the intrinsic size of the NSView. I want to define the size of the NSView and have auto layout work based on that. I added this code to the custom view (labelView):
override var intrinsicContentSize: NSSize {
return NSSize(width:100, height:100);
};
And it is indeed called; but apparently ignored. As a test, I have on the same row some other labels, and the height for the row is always set to the largest of the row text heights (including the label in the custom view); but the length is set to the longest of column text fields, ignoring the label in the custom view. And anyway, I want to arbitrarily make the NSView a certain height and length, as I tried (but failed) to do with the intrinsicContentSize.
NSStackview seems to do the right thing; but NSGridView does not.
I can force the width of a particular column with
grid.column(at:0).width = 400;
but want I really want to do is define the size of the NSView, and let autolayout use that as a building block.
This strikes me as a conceptual error on my part, so if someone could explain these NSGridView-autolayout-NSView subtleties, I think many might benefit.
I was having the exact same issue, tried to use custom NSView's inside a NSGridView and couldn't get them to draw correctly. What finally worked for me was setting the following:
let gridSize = 5
let cellSize: CGFloat = 50
gridView.xPlacement = .fill // this was key part of the solution
gridView.yPlacement = .fill
for i in 0 ..< gridSize {
gridView.row(at: i).height = cellSize
gridView.column(at: i).width = cellSize
}
Note that I'm setting the size of each cell with the row height and column width of the NSGridView, and not using the NSView size, but this is the only way I got it working.
I'm dynamically adding NSTabViewItem in NSTabView, using this code:
#IBOutlet weak var inputTabs: NSTabView!
...
let rgbInputController = ForegroundRGBInputController(nibName: NSNib.Name(rawValue: "RGBInputView"), bundle: nil)
let rgbInputItem = NSTabViewItem(identifier: "RGB")
rgbInputItem.label = "RGB"
rgbInputItem.view = rgbInputController.view
self.inputTabs!.addTabViewItem(rgbInputItem)
The view is added, but not correctly displayed.
RGB tab with size issues
After playing with the tabs, and the App width, the tab finally displays correctly.
RGB tab displayed correctly
I believe this is a constraints issue, but I have difficulties to fix it.
Any suggestion?
Thanks,
Have you tried calling setNeedsLayout on the input controller view? That should flag that it needs to be laid out again. You could also try invalidateIntrinsicContentSize, as the intrinsicContentSize of your view may be being used to indicate its initial width and height.
I Have a Horizontal Collection View with Cells containing a label that has auto layout that expands on the size of the cell view.
Im using Xcode 8 and Swift 3.
How can I make so that my cell size is dynamic based on the text? I mean, I want it to expand, so that Otro Text... Reads complete instead of how its shown right now with the dots.
As You can see on the screenshot, now my large text gets trimmed (The Collection view, is on the area that has the Texts: Todo, Otro Text... Test1).
Hope someone can help or orient me on finding a solution.
You need to make sure that the you add leading and trailing constraint to the label and do not add any width constraint.
Next step is to give an estimatedSize in you collectionViewLayout.
Example
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = CGSize(
width: 100, height: collectionView.bounds.size.height)
}
You need to set the estimatedItemSize in your UICollectionViewLayout to be able to enable self-sizing cells. It is not possible from Storyboards, only available through code.
Title should read: Automatically adjust width of the containing NSWindow of a view based NSTableView based on NSTableCellView's NSTextField content intrinsic content size.
A bit like this other question, I would like to implement an autocompletion NSWindow with an NSTableView inside it that adjust to the width of the length of the available autocompletions implemented as NSTextField inside an NSTableCellView. Each autocompletion should obviously be displayed on one line...
The previous question has been answered but was only related to the hight of the NSTableView. I would like to know how to do the "same" for the width. I would like to implement the solution as much as possible using auto layout.
I've tried to set the horizontal "Content Hugging Priority" and the "Content Compression Resistance Priority" to the maximum of 1000 for each view element participating in the final display of the NSWindow. I was thinking that the intrinsic content size of the NSTextField would force all other elements to adjust but it does not work.
Setting the NSTableColumn width does not work either since the NSClipView of the NSScrollView is not modified by this width: the NSScrollView adjusts and creates horizontal scroll bars to cover the entire "document".
Here is a link to a sample project to demonstrate the problem:
sample project
Any help would be greatly appreciated!
I fixed the problem using this code with the scrollViewWidthConstraint being an IBOutlet to the NSScrollView width constraint, localTableView being an IBOutlet to the NSTableView and tableColumn being an IBOutlet to the NSTableColumn (the only one in my case).
Note: The linked project on GitHub has been updated with the changes.
override func viewDidLoad() {
super.viewDidLoad()
self.updateTable()
}
func updateTable() {
localTableView.reloadData()
var computedWidth: CGFloat = 0
for var row = 0; row < 10; row++ {
let tableCellView = self.tableView(localTableView, viewForTableColumn: tableColumn, row: row) as! NSTableCellView
computedWidth = max(computedWidth, tableCellView.textField!.intrinsicContentSize.width)
}
scrollViewWidthConstraint!.constant = computedWidth
scrollView.needsUpdateConstraints = true
}
I have put a label in a text box and I want to shift this label to left side after tapping this text box. In the following screenshot 'hello' is a label and I want to shift it left after tapping on the text box.
I wrote the following code but the 'textFieldDidBeginEditing' function is not called
#IBOutlet weak var lblhello: UILabel!
func textFieldDidBeginEditing(numtxt: UITextField!) { //delegate method
lblhello.frame = CGRectMake(98, 156, 42, 21)
}
I'm making the assumption based on previous comments that you want to manually specify the frame size, and aren't using constraints.
First off, you need to add UITextFieldDelegate to your viewController.
This is done like so in the beginning of your VC class:
class yourViewControllerName: UIViewController, UITextFieldDelegate {
Then you want to specify the delegate of your UITextField, (most likely in viewDidLoad)
yourTextFieldName.delegate = self
Now you can use the textFieldDelegate functions. The on you're looking for is probably this:
func textFieldDidBeginEditing(textField: UITextField) -> Bool {
lblhello.frame = CGRectMake(160, 200, 60, 40)
return true
}
If everything is set up correctly that should change the frame of lblhello when a user begins editing your UITextField.
One common problem I often hear for people saying this doesn't work. Is caused by the label being specified in viewDidLoad(). Most of the time you want to declare the label before viewDidLoad(), otherwise functions like this doesn't have access to it.
In case you want to move it back to it's original position afterwards. You do almost the same as you did in textFieldDidBeginEditing except you use textFieldDidEndEditing instead.
However, on a side-note. I do suggest getting used to using constraints rather than setting the frame for things like this.