iOS - how to implement custom table view cell selection/unselection? - uitableview

I'm working with a UITableView, and as far as I understand it has grey or blue selection of rows. Is there a way to override UITableView cell selection behavior (define a "selected" style)?
If there is not, would a vertical collection view work as an imitation of a table view with custom selection?

According to the UITableViewCell Class reference, you are limited to:
UITableViewCellSelectionStyle
The style of selected cells.
Declaration
SWIFT
enum UITableViewCellSelectionStyle : Int {
case None
case Blue
case Gray
case Default
}
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/swift/enum/UITableViewCellSelectionStyle
So you would have to develop your own custom action on selection to change the background color.

Related

Expand and collapse cells in tableview

I have a tableview. Some cells contain images, other text.
I want to be able to collapse and expand the cells. In order to be able to do so I did the following:
I created a variable isExpanded = true
In cellForRowAt I check if the cell contains text and then...
if textIsExpanded {
cell.textLabel?.sizeToFit()
cell.textLabel?.numberOfLines = 0
}
so that the cell can be as tall as the text inside of it.
In the action I toggle textIsExpanded and reload the table:
textIsExpanded.toggle()
table.reloadData()
This procedure perfectly works with tableviews only containing text.
Something that would work was expanding the if statement and in the false branch calling:
cell.textLabel?.invalidateIntrinsicContentSize()
cell.textLabel?.layoutIfNeeded()
BUT this doesn't work when I toggle the variable, this only works on launch.
How can I collapse and expand back the cells in my tableview?
Create your cell with a stack of two views, Upper view and lower View, Add a Bool key to your Model isExpandable that is triggered and changed on didSelect and check on this to hide or show your view, EIther keep the text as text or TextView up to you.

How to add unique insets to specific UITableViewCells?

I have a UITableView whose insetsContentViewsToSafeArea property is set to false - this makes the tableView span the width of the screen.
The amount and different types of cells are driven by the server, so there's no way of knowing the content of the tableView.
What I'd like to to:
Assign unique insets to certain cells only.
I can't post a screenshot, so I'll try to make a quick doodle:
These three cells are all in the same UITableView:
|[This is one cell that goes edge-to-edge]|
|[Here's another one]|
|-----This cell needs its own insets-----|
Question:
What's the best way to achieve this?
What I've tried:
Overriding layoutMarginsDidChange
Trying to add layoutMargins directly in cellForRowAtIndexPath...
Create a UITableViewCell subclass for the cell with custom insets.
Then you have 2 options --
Add a subview to cell's contentView with constraints -- these will correspond to your desired insets. This view will act as your " pseudo contentView" (add cell content to it)
Play around with contentView's insets. (not sure if it'll work)
I hope this will get you started.
You can use the cell subclass for all cell cases too if you want -- with an enum style which you can set in cell for row.
enum Style {
case edgeToEdge
case withInset(inset: UIEdgeInset)
}
inside cell subclass
var insetStyle: Style = .edgeToEdge {
didSet {
//update the constraints of the pseudo content view
}
}

ios - how to determine if a cell indexPath changed in uitableview

I have two questions :
1- Is it possible to know if a cell indexPath.row has changed in a UITableView ? for example if I have an element at index (0) and then I add another one, the first element will be at index (1). Is it possible to detect this change ?
2- Is it possible to fnd the index of an element by the cell title ? for example I have X,Y,Z element in the tableview and I want to know in which cell 'X' is placed ?
thanks guys,
Generally speaking, it's common practice to isolate model and view. What I mean by this, is separate the storage of the data and the view that's rendering it.
For example, you may be creating a table view of color names. Therefore, you could store an array of color names as a property of your view controller
class UIColorViewController: UITableViewController{
let colors = ["Black", "Blue", "Yellow"]
As I'm sure you're doing, you can assign the view controller as the data source of the table view so you can tell it how many sections you want, the number of rows you want in a section, and what to render onto a cell.
In this elementary example, the number of sections could be 1 and the number of rows in this section would be the length of the colors array. Now when rendering data onto the cell, you simply index the colors array by the index path.
fun tableView(UITableView, cellForRowAt: IndexPath){
var color = colors[indexPath.row]
cell = //dequeue cell
cell.textLabel?.text = color
return cell
}
So by separating the data from the view, if you want to find what cell a particular value is at, you can simply search through the array where the color is at and the index returned would be equivalent to what cell this color is or will be at depending on if that cell has been rendered onto the screen yet.
For example using the colors array, if I were looking for "Blue"
for (index, color) in self.colors.enumerated{
if color == 'Blue'{
print("Found Blue at index \(index)")
}
}
When you want to add a cell or delete a cell, you simply modify the colors array which is storing the model data, perform the appropriate table view related action, and the invariant remains that the index of the color in the array would be equivalent to the index of the cell in the table view.

Conditional formatting in google sheets to inherit formatting from other cell

I've been trying to figure out how to apply conditional formatting to the background of a cell. I've searched the internet but haven't been able to find anything related to this.
I am interested in formatting a cell conditionally, so that if the contents are equal to a text string, the background color will inherit the background color of another cell.
Does anyone know if this is possible and how to accomplish it?
This is the quasi-code for the functionality I am looking to achieve:
If (cell contents are empty) then
Apply background from cell offset two cells to the right
End If
This is not possible with plain conditional formatting, you'll need an onEdit function.
function onEdit(e) {
var r = e.range;
if (e.value.length > 0) {
var reference = e.source.getActiveSheet().getRange(r.getRow(), r.getColumn()-2)
var color = reference.getBackground();
r.setBackground(color);
} else {
r.setBackground("white");
}
}
Note that this will not update the cell's background color when you change the reference cell's background color.

Animate a slide-in details view within a UITableViewCell

I have a UITableViewCell that is using auto-layout. When a user selects the cell, I want to display extra information in a details view that slides downwards, extending the bottom of the cell.
I'm having trouble figuring out the correct way to do this.
The transitionFromView:toView:duration:options:completion: method does not seem appropriate, because I am not replacing one view with another.
The transitionWithView:duration:options:animations:completion: method seemed like it should do the trick, but I can't figure out the correct way to achieve my goals using it.
This is what I tried initially (C#, but Objective-C/Swift equivalents should be obvious):
private void AnimateDetailsIntoView()
{
this.detailsView.Hidden = true;
this.ContentView.ConstrainLayout(() =>
this.detailsView.Top() == this.nameLabel.Bottom() &&
this.detailsView.Bottom() == this.ContentView.Bottom() - Layout.StandardSiblingViewSpacing &&
this.detailsView.Left() == this.nameLabel.Left() &&
this.detailsView.Right() == this.nameLabel.Right());
this.AddSubview(this.detailsView);
UIView.Transition(
this,
0.2,
UIViewAnimationOptions.ShowHideTransitionViews | UIViewAnimationOptions.TransitionFlipFromBottom,
() => { },
() => { });
}
This results in the table cell "spinning around", but the details view does not actually show. Even if I remove the line that hides detailsView, I still don't see it after the animation.
I suspect this is layout related, but am unsure how to "grow" the cell vertically.
Can anyone tell me what I'm doing wrong?
PS. I realize there's more to do once I get the initial animation working. I'll have to animate any previously selected cell up and remove its details panel.
As per the OP wants to expand and collapse the cell, following are the procedure to achieve it:-
Design your whole detail cell in a single prototype cell.
Now tableView heightForRowAtIndexPath: specify 2 sizes one for collapse cell and another size for (expanded)detailed cell,by giving a condition something like BOOL variable"isExpanded".
Now on didSelect of tableView or in the button's action if you are using button in cell, just store the value of indexpath.row to determine which row to expand and add this code to reload the row, this will easily do the animation trick of expand
[tbl beginUpdates];
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom];
[tbl endUpdates];
Same goes for collapsing a cell, just some logic tweaks, which you can easily do.

Resources