TableViewCell disclosure indicator position - ios

I have a custom tableviewcell with the standard disclosure indicator positioned in the centre vertically by default. How can I move this standard disclosure indicator vertically like in the iOS mail app?

You can adjust the position of the default accessory by subclassing your cell and finding the UIButton in the cell's subviews (which represents the indicator) and holding a reference to it. You can then simply update the frame of the accessoryButton in layoutSubviews or wherever you choose like so:
class CellSubclass: UITableViewCell {
var accessoryButton: UIButton?
override func awakeFromNib() {
super.awakeFromNib()
accessoryType = .DisclosureIndicator
accessoryButton = subviews.flatMap { $0 as? UIButton }.first
}
override func layoutSubviews() {
super.layoutSubviews()
accessoryButton?.frame.origin.y = 8
}
}

You can not move standard disclosure indicator vertically.
If you want to achieve this functionality, then you need to use your custom cell and use image of disclosure indicator and then you can set this image with button on where ever you want to place.
Or you can use view also as a accessory indicator and add as a subview of UITableViewCell
[cell.contentView addSubview:aView];
You can read more over here disclosure indicator

You can modify the Layout Margins to Fixed on TableViewCell in the .xib and then set the right margin to the desired value.

Related

Swift: TableViewCell hightlights the whole cell when selected instead only the image view

so here is how my setup looks like: Screenshot
As you can see I use TableViewsCells then I place ImageViews inside the cell. But as you can see on the screenshot whenever I hold my finger over the tableview it hightlights the whole cell area not the ImageView that acts as background ,so how can I make sure that it highlights the background Image only? Thanks
You can set the selectionStyle to .none in your UITableViewCell then override isSelected.
override var isSelected: Bool {
didSet {
// do whatever you want to your image here
}
}

How to increase UICollectionViewCell height and show a label after button click in Swift

Let say I have a UICollectionViewCell and below is my layout of the cell
LabelOne || LabelTwo || Button
In my CollectionViewController, I set cellForRowAtIndexPath = 30. Now, I want to show a label named labelThree under label two and increase my cell height = 60 after button pressed. Below is the layout what I want to accomplish after button press
LabelOne || LabelTwo || Button
Label Three
Does anyone have any suggestions? Thanks in advance!
Create custom cell using auto-layout and make sure to set the height of each label and button. Also make sure to set set the top and
bottom constraints for all components. This way, the cell will have
it's height.
At start, set the visibility of Label Three as hidden.
Set the visibility of Label Three as visible on button click.
Call cell.layoutIfNeeded just after that to reset the cell height.
In cellForRow atIndexPath:
cell.updateConstraint = {
self.collectionView.beginUpdates()
self.collectionView.endUpdates()
}
In collectionview Cell:
var updateConstraint: () -> Void = {}
func addLabel() {
// add three label
// make cell new constraint
self.updateConstraint()
}

UITableViewCell selection style changing background color for all subviews

I'm writing in swift, using the storyboard, and I'm working with iOS 10.
I have a UITableViewCell composed of some subviews (they're UIViews). Some of those subviews have a background color.
The selection style on the cell is Default (gray).
When I tap the cell, the cell becomes gray. Good. However, the background color of each subview in the cell is also changed automatically to match the selection color (gray) of the cell. Not good.
How can I best prevent this behavior? I don't want the background colors of the subviews in the cell to change.
NOTE: I don't consider it a very good solution to do my own selection by listening for the didSelectRowAtIndexPath delegate method and then setting the background color of the cell's content view. Perhaps this is the only way, but I want to see if there are other options first.
UPDATE:
Just to clarify, another reason I don't like the above solution of listening for the delegate is that it fixes the issue per cell. So if I have other custom cells that use the same subviews, I would have to implement the same fix. I want something that fixes this at the view level, rather than the cell level. So that when I use those same views in other custom cells for different table views, I don't have to worry about it.
This way is better than listening to the didSelectRowAtIndexPath for sure.
Play with these properties in your custom cell class:
override var isSelected: Bool {
didSet {
if isSelected {
//play with colors
print("selected")
} else {
//play with colors
print("deselected")
}
}
}
override var isHighlighted: Bool {
didSet {
if isHighlighted {
//play with colors
print("highlighted")
} else {
//play with colors
print("not highlighted")
}
}
}
Disable selection style:
cell.selectionStyle = UITableViewCellSelectionStyleNone
And tricky one:
cell.selectedBackgroundView = UIView()

How do I add an ImageView into a table cell on button click?

I am trying to do something like this:
When the user clicks "Add Page," a new grouping shows up below it. Now, I decided to use Table View cells in order to achieve this. After following various tutorials and looking up similar Q&As, I am able to add cells on button click with UILabel and have the cell height be dynamic depending on the content but now I am trying to figure out how to add ImageViews and place buttons within a cell.
I've created a custom cell class:
class PageCell : UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = UITableViewCellSelectionStyle.none
setupViews()
}
...
... // other random code here
let imgView : UIImageView = {
let imgview = UIImageView()
imgview.frame = CGRect(x: 100, y: 150, width: 150, height: 140)
imgview.tintColor = UIColor(red: 0.73, green: 0.2, blue: 0.3, alpha: 1.0)
imgview.translatesAutoresizingMaskIntoConstraints = false
return imgview
}()
func setupViews() {
addSubview(pageLabel) // the label that I got working
addSubview(imgView) // can't get this working
...
// constraint info here
}
}
And back in my TableViewController:
class TakePhotosVC: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(PageCell.self, forCellReuseIdentifier: "cellID")
}
// return the actual view for the cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let pagecell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath) as! PageCell
// set more stuff here
}
... // more code
}
My issue is that I am trying to get a box showing where the ImageView is that the user can click on to load in a picture. I am unsure how to do that and place all the relevant buttons as well (Trash, X, etc.)
Any help would be greatly appreciated.
EDIT
Okay, I was trying to follow this tutorial and I can't quite get it to work. In my prototype cell, I see this:
But the result is this:
I made the UIImageView have a background so I can see it. I have two constraints for the UIImageView which are: width = 240, height = 128 and two constraints for the Page Label which are: width = 240, height = 21. Two questions: why are my elements not placed correctly even though I have it correctly placed in the Storyboard? And why is the cell height not dynamically resizing to accommodate the elements?
I have these two lines in my viewDidLoad method of the TakePhotosVC but it doesn't seem to do anything.
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 200
If it's relevant, I get this warning when I run the Simulator.
Warning once only: Detected a case where constraints ambiguously
suggest a height of zero for a tableview cell's content view. We're
considering the collapse unintentional and using standard height
instead.
EDIT 2
I got it to work. For any poor souls reading this after me, you have to click on those dotted pink lines in the Constraints window editor and then click "Add X Constraints" in order to get the ImageView to center and stuff.
My issue is that I am trying to get a box showing where the ImageView
is that the user can click on to load in a picture. I am unsure how to
do that and place all the relevant buttons as well (Trash, X, etc.)
I am not sure if I understand you correctly. You have a cell with an UIImageView. But you want to show a box to visually indicate where the user should touch to add an UIImage (?)
Why not simply add a UIButton on top of the UIImageView with the exact same frame size, and on touch, you fire your action to add the image, and once the image is successfully added, you can set the UIButton to hidden.
If the user deletes the image with the trash button, you simply show the UIButton again by hidden = NO.
Other solution:
Add a border to the UIImageView with custom colors and add a UITapGestureRecognizer to fire an action. (Make sure you set the UIImageView to userInteractionEnabled = YES;
You can allso add a Placeholder image to the UIImageView when there is no image set, with your custom design.
The easiest approach would be to use a xib instead of placing the buttons programmatically. To do this, add a new file and select xib. In a xib, you can pre-make a tableviewcell with the image view, and you buttons placed for you already with constraints. Then, you can subclass this table view cell and connect the image view and buttons with ib outlets and ib actions to access the buttons and image view. Then, in your cellForRow function, load the xib like this:
Bundle.main.loadNibNamed("NameOfNib", owner: self, options: nil).first as! NameOfSubclass
I would advise to read more on xibs and nibs.

iOS - How can I click a UIButton behind UITableView with transparent header

I have a UIButton at the bottom layer of the UIViewController.
And I have a UITableView (full screen size) on top of the UIButton, the UITableView has a header (UIView) which has a transparent background which could be able to see through and show the UIButton.
The UIButton is not clickable even when the button appear behind the tableview header.
My tableView's cell and the header of the tableView has buttons on it, so I could not set headerView.userInteraction = true or tableView.userInteraction = true
I have tried to use pointInside:withEvent: and hitTest:withEvent:, UIButton is still not clickable in both cases.
Any suggestions? Thanks
You could use UITapGestureRecognizer for example like this:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
...
let headerViewGesture = UITapGestureRecognizer(target:self, action:#selector(MyClass.headerViewTap(_:)))
headerView.addGestureRecognizer(mainViewGesture)
...
}
func headerViewTap(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.Recognized
{
let touchLocation = recognizer.locationInView(recognizer.view)
print(touchLocation)
if CGRectContainsPoint(myButton.frame, touchLocation) {
print("button was touched")
}
}
}
Please try bringSubviewToFront to get the button clickable.
self.view.bringSubviewToFront(yourButtton)
Or you can check it in storyboard whether the button is inside some view, And add make sure the button is placed properly in storyboard. The button should be below the table view like in the sample picture.
You can try both the ways and let me know if you have any doubt.

Resources