I have a dropdown menu for the user to be able to change the displayed data. When the user chooses to select an item, among others a button is being updated.
Let's say in the beginning the buttons title was "Cars", and after selection of another item it is "Example", the button is being displayed like this: "E...le".
How can I adjust the button size to its title?
Code for the button:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...
setButtonCars()
...
let tv: UITableViewController = self.children[0] as! HomeTableViewController
print(self.children[0])
tv.tableView.reloadData()
tv.viewWillAppear(true)
buttonDropdown(self)
tableView.deselectRow(at: indexPath, animated: true)
}
func setButtonCars() {
carsButton.setTitle(currentCar.uppercased(), for: .normal)
let icon = UIImage(named: "chevron")!
carsButton.setImage(icon, for: .normal)
carsButton.imageView?.contentMode = .scaleAspectFit
carsButton.imageEdgeInsets = UIEdgeInsets(top: 11, left: 3, bottom: 1, right: 0)
carsButton.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
carsButton.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
carsButton.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
}
EDIT:
I forgot to mention that the button is inside of a UIBarButtonItem.
Add .sizeToFit() after changing the title:
func changeTitle(_ newTitle: String) -> Void {
carsButton.setTitle(newTitle, for: .normal)
carsButton.sizeToFit()
}
This might be happening because of fixed width of the button which might not be enough to hold icon and text. Try increasing the button width.
Set constraint for minimum width of button. You might also like to give maxwidth also in case the text is too large.
Change the Cars button's frame(increase width) such that is can contain the 'Examples' text.
Hope this helps.
Related
I have a problem with implementing custom animation while swiping table view cell.
The goal is to change cell background color while swipe cell with animation.
Ideally, it's perfect if background color changes depending on the offset on the x-axis.
Or if it's impossible or difficult to do it, it would be good to finish the animation when swiping is finished.
And the background color of the cell should be the same as the action button's one.
"Swiping" means gesture that makes buttons show like as default delete action.
The follow code is current one.
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "", handler: { (action,view,completionHandler ) in
completionHandler(true)
})
action.image = UIGraphicsImageRenderer(size: CGSize(width: 30, height: 30)).image { _ in
UIImage(named:"sell_btn")?.draw(in: CGRect(x: 0, y: 0, width: 30, height: 30))
}
action.backgroundColor = UIColor(hex: "#F4F4F4")
tableView.backgroundColor = .red
let confrigation = UISwipeActionsConfiguration(actions: [action])
return confrigation
}
This code changes the background color when this function called.
PS: I've tried MGSwipeCell and SwipeCellKit too, but they don't provide me exact thing what I want.
Thanks.
I am trying to add Trailing Swipe Actions for UITableView using UIContextualAction but the icon is not visible because the icon becomes white and the background is also white and when I change the background color it is visible. Please help me set the icon as such with its color. I tried searching for tint color property but there is no such property. Below are the codes I have tried.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .normal, title: nil, handler: { (action,view,completionHandler ) in
// Delete the row after API
})
//Solution 1
delete.image = UIImage(named: "deleteicon")
// Solution 2
delete.image = UIGraphicsImageRenderer(size:CGSize(width: 30, height: 30)).image { _ in
UIImage(named:"deleteicon")?.draw(in: CGRect(x: 0, y: 0, width: 30, height: 30))
}
// Solution 3
edit.backgroundColor = UIColor(patternImage: UIGraphicsImageRenderer(size:CGSize(width: 30, height: 30)).image { _ in UIImage(named:"favouriteinactiveicon")?.draw(in: CGRect(x: 0, y: 0, width: 30, height: 30))})
let confrigation = UISwipeActionsConfiguration(actions: [delete])
return confrigation
}
I have a custom button with a right-aligned arrow icon.
When it's highlighted with a tap, only the arrow icon is highlighted. The text remains white instead of turning gray like the icon does.
This is the code (scoped in a subclass of UIButton):
let rightIcon = #imageLiteral(resourceName: "disclosureIndicator")
setTitleColor(.white, for: .normal)
setBackgroundImage(rightIcon, for: .normal)
guard let image = backgroundImage(for: .normal) else { return }
titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width)
I've also overridden the backgroundRect property.
override func backgroundRect(forBounds bounds: CGRect) -> CGRect {
guard let image = backgroundImage(for: .normal) else {
return super.backgroundRect(forBounds: bounds)
}
return CGRect(
x: frame.width - (image.size.width + 20),
y: (frame.height / 4) + (image.size.height / 4),
width: image.size.width,
height: image.size.height)
}
I've also tried setting the button image (i.e. setImage(rightIcon, .normal)) instead of setting the button background image, but it didn't work.
I've also tried setting the highlight color for the icon and the title to gray, but that didn't work either.
I want both the text and the icon to be highlighted when the button is tapped, but I can't seem to find a way of achieving this. Is it genuinely impossible to do?
Setting the button type to System instead of Custom solved the issue. Now they both highlight like they should.
I'm trying to make this animation
so i want that when the user picks up with his finger the cell get smaller and then when it stops pressing come back on the original size, important is that i'm not using a custom cell but the default UITableViewCell, here is my code with whom i tried to do the animation (after watching old question and tutorial)
var originalCellSize: CGRect!
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
print("I'm Highlighted at \(indexPath.section)")
guard let cell = tableView.cellForRow(at: indexPath) else {
return
}
originalCellSize = cell.frame
UIView.animate(withDuration: 0.1, animations: {
cell.frame = CGRect(x: cell.frame.origin.x + 20, y: cell.frame.origin.y, width: cell.frame.width - 40, height: cell.frame.height)
})
}
func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) else {
return
}
UIView.animate(withDuration: 0.1, animations: {
cell.frame = CGRect(x: 0, y: self.originalCellSize.origin.y, width: self.view.bounds.width, height: 180)
})
originalCellSize = .zero
}
i don't know why but something is wrong and the animation do not work, can someone help me (it also happens that after pushing on the cell this changes position in a definitive way)
Don't manipulate UITableViewCell's frame directly.
Use it's transform property.
Likewise:
Scale down the cell upon highlight / selection.
UIView.animate(withDuration: 0.3) {
cell.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
cell.layoutIfNeeded()
}
Scale back to normal:
UIView.animate(withDuration: 0.3) {
cell.transform = CGAffineTransform.identity
cell.layoutIfNeeded()
}
Don't forget to call cell.layoutIfNeeded() before the animation block and inside (right after assigning the CGAffineTransform).
You can approach the problem in a different way. You can resize a view inside the Table view cell.
Like you can keep a view with white color and cell background as grey color. In highlight delegate method, you can change the frame of UIView inside the cell and on unhighlight method, you can resize to back to cell size.
WhenEver You want to change layout of cell you must need to call cell.layoutIfNeeded().
Set flag that cell should change size.
Add flag check for heightForRowAtIndexPath
On highlighting use:
table.beginUpdates()
table.reloadRowsAt(...)
table.endUpdates()
Should work just fine.
I'm not sure you can just change frame of the cell. So you can also try try to change cell's content view size. Or your custom view frame itself.
I have a long string:
"A very long string"
that won't be displayed fully in a UITableView, i.e. it gets truncated to:
"A very long s..."
Is it possible to have this text in a UITableViewCell automatically scroll horizontally and indefinitely so that it loops around? Perhaps this can be achieved using an attributed string?
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)
cell.textLabel?.text = "A very long string"
cell.textLabel?.textAlignment = .center
Thanks in advance for any help with this!
EDIT (my attempt at a solution proposed)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)
let frame = CGRect(x: 0.0, y: 0.0, width: cell.bounds.width * 2.0, height: cell.bounds.height)
let scrollView = UIScrollView(frame: frame)
cell.addSubview(scrollView)
let label = UILabel(frame: scrollView.bounds)
scrollView.addSubview(label)
label.text = "some very long text that doesn't quite fit"
label.textAlignment = .center
let newFrame = CGRect(x: label.frame.width, y: 0, width: label.frame.width, height: scrollView.frame.height)
UIView.animate(withDuration: 1.0, delay: 0.0, options: [.repeat, .autoreverse], animations:( { void in
scrollView.scrollRectToVisible(newFrame, animated: true)}),
completion: ({ completed in }))
}
Scrollview inside a table view is a bad idea. Instead you can enable the automaticDimension and estimated row height and tableView will manage the cell height automatically.
self.tableView.estimatedRowHeight = 44
self.tableView.allowsMultipleSelection = true
So as per the content each cell will manage its own height.
Hope this would be helpful!
You would have to make a custom tableview cell, which has a custom scrollview which handles UILabel scrolling. You would need to assign the text and measure the width. If it is wider than the containing view then add a second duplicate label to its right. You then need to animate the scrollview to the left by the width of the label. On complete, jump back to offset 0,0 and animate again.
Usually, to have special effect as such will require customization of an UILabel. To make my life easier, I will always try to search if there is already a working library out there for me to consume.
A simple Google search brings me MarqueeLabel, hope it helps!