iOS - UITableViewCell's image go ontop of table upon selection? - objective-c

I have 2 tables in one view. Table A lists a bunch of users. Table B lists a users objects. When a row is selected in Table A, Table B is reloaded with the objects that belong to that user.
So when a user selects a row in Table A, the image in the background of the cell changes to the highlighted version of the image.
Here is the normal version of the background image:
Here is the highlighted version of the background image:
As you can see, the highlighted version has a small arrow on the right of it. This arrow is beyond the width of the table cell the table itself. When the row is selected, the image changes as it should, but the image is sized down to fit the whole image into the cell.
What I would like to happen is the image goes outside of the table, or on top of the table for that selected row.
One possible solution I thought was to center the table on the selected row and then overlay that image, but if the user was to try to scroll through the table, the image would need to move and that would be a big pain.
So what I would like to know is it is possible to extend the cell's size beyond the table one it is selected?
Thanks in advance!
EDIT:
The following does not work, just in case anyone was going to try:
[cell setFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width+20, cell.frame.size.height)];

Setting a views clipsToBounds property to NO will allow the view to draw outside of its own frame.
In your UITableViewController subclass:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do what you normally do here, if anything then add...
self.view.clipsToBounds = NO;
}
Doing this has a side effect where you will see full cells be created at the bottom or top of the tableview instead of them scrolling partially into view. Either put the table view into another view that has clipsToBounds set to YES, align the edges of the table view with the edges of the screen, or have views covering over the bottom and top (like a UIToolbar and UINavigationBar normally would).
To get the UITableViewCell's selectedBackgroundView to extend past the table view's frame create a subclass of UITableViewCell and override the layoutSubviews method.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"YQGyZ"]];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"CQXYh"]];
self.textLabel.backgroundColor = [UIColor clearColor];
self.detailTextLabel.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect frame = self.selectedBackgroundView.frame;
frame.size.width += 13; // where 13 is the size of the arrow overhang from the same images
self.selectedBackgroundView.frame = frame;
// You can also change the location of the default labels (set their background colors to clear to see the background under them)
self.textLabel.frame = CGRectMake(70, 0, 148, 30);
self.detailTextLabel.frame = CGRectMake(70, 30, 148, 30);
}
Good luck.

I would recommend modifying the image resource of the unselected cell background such that it is the same width as the selected background, but just has a transparent rectangle on the side.

Related

UIVIew from XIB with Autolayout to UItableView Header

I am writing because I have a problem with the Auto Layout.
I'm trying to create a simple view in InterfaceBuilder with Auto Layout I want to load code and enter as a header of a table (not as header section). I explain briefly what are the characteristics.
The imageView must be square and must be as wide as the screen.
The space under the picture to the bottom of view that contains the button and label must be high 50 points.
Between image and button has to be a fixed distance of 12 points.
Between image and label must be a fixed distance of 13 points.
All these features are able to get them with Auto Layout. I added a constraint to the aspect ratio of the image (1: 1) and the various constraints for distances. all right.
The real problem is that by launching the app on iphone 6+ simulator (414 points of width), the image (with the label and button) goes above the cells.
Enabling various transparencies I noticed that the superView of Image View, only increase the width. It does not increase its height! How do I fix?
This is the code:
- (void)viewDidLoad{
//...
PhotoDetailsHeaderView *hView = (PhotoDetailsHeaderView *)[[[NSBundle mainBundle] loadNibNamed:#"PhotoDetailsHeaderView" owner:self options:nil] objectAtIndex:0];
hView.delegate = self;
self.tableView.tableHeaderView = hView;
//...
}
This is how I create the xib:
and this is how it is on the simulator, the green box is Uiimageview and the yellow box (under green box) is the mainview (or superview):
How can fix it?
Many thanks to all!
You'll need to add a property to store your PhotoDetailsHeaderView:
#property (nonatomic, strong) PhotoDetailsHeaderView *headerView;
Then calculate its expected frame in viewDidLayoutSubviews. If it needs updating, update its frame and re-set the tableHeaderView property. This last step will force the tableView to adapt to the header's updated frame.
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
CGRect expectedFrame = CGRectMake(0.0,0.0,self.tableview.size.width,self.tableView.size.width + 50.0);
if (!CGRectEqualToRect(self.headerView.frame, expectedFrame)) {
self.headerView.frame = expectedFrame;
self.tableView.tableHeaderView = self.headerView;
}
}
The problem is probably that in iOS you have to reset the header of the table view manually (if it has changed its size). Try something along these lines:
CGRect newFrame = imageView.frame;
imageView.size.height = imageView.size.width;
imageView.frame = newFrame;
[self.tableView setTableHeaderView:imageView];
This code should be in -(void)viewDidLayoutSubviews method of your view controller.

UITableVIew header without bouncing when pull down

I have a UITableView which I am able to add a header view to fairly easily. Many apps (like Facebook, for viewing events) have a headerView that when you pull down, the header view stays put but the rest of the table (the UITableViewCell's) are bouncing. When scrolling up the header disappears. How can I achieve this functionality?
Right now when I pull down the UITableView, even the headerView bounces as well
You can achieve this effect quite easily by adding a subview to the header view and adjusting its frame or transform when the table view is scrolled beyond the top, i.e. the y component of its contentOffset becomes negative.
Example (in a UITableViewController subclass):
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat headerHeight = 64.0f;
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, headerHeight)];
UIView *headerContentView = [[UIView alloc] initWithFrame:headerView.bounds];
headerContentView.backgroundColor = [UIColor greenColor];
headerContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[headerView addSubview:headerContentView];
self.tableView.tableHeaderView = headerView;
}
//Note: UITableView is a subclass of UIScrollView, so we
// can use UIScrollViewDelegate methods.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat offsetY = scrollView.contentOffset.y;
UIView *headerContentView = self.tableView.tableHeaderView.subviews[0];
headerContentView.transform = CGAffineTransformMakeTranslation(0, MIN(offsetY, 0));
}
(to keep it simple, I've just used the first subview of the actual header view in scrollViewDidScroll:, you may want to use a property for that instead.)
Your UITableView is most likely working properly. Section headers are sticky by default in Plain style tables. Meaning as you scroll down the header stays at the top of the UITableView's frame until the next section header pushes it out of the way. The opposite occurs when you scroll up. Conversely you get the sticky behavior on section footers at the bottom of the UITableView's frame.
EDIT Misunderstood the original question:
I would suggest using a section header rather than the table view header to get the sticky behavior you're looking for.
Include a section in your data with no rows and put your table header's view in that section header view.
you can use this line in view did load: (swift 5.6)
tableView.bounces = false
There is 2 ways you can set the table header:
Using the .tableHeaderView property directly (this header scrolls with the table)
Overriding the - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section function (this header stays static with the section)
By the sounds of it you should use the 2nd method instead of using the .tableHeaderView property

UITableView does not respond to touches at transparent areas

I have a UITableView with a transparent backgroundColor, and the cells inside are initialized with the following code
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, CGRectGetWidth(self.contentView.frame), 180)];
self.label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.label.text = #"test";
[self.contentView addSubview:self.label];
}
return self;
}
Each row has a height of 200, and the label doesn't fill up the entire cell. There will be transparent portions in between each cell. When I try to scroll the table by touching those transparent portions, the touches are completely ignored. I am aware that as of iOS5, touches on views will be ignored. What can I do to solve this?
Things I've tried that don't work:
Setting a transparent or hidden or alpha = 0 UIView to act as a fake background of the tableView
Same deal, touches are ignored.
Creating a subclassed UIView on top of the tableView, and the subclassed UIView uses tableView as the nextResponder
Apparently UITableView doesn't use touchesBegan/cancelled/ended/moved, so this doesn't work. I don't think it's wise to implement my methods to scroll the UITableView either.
Setting the backgroundColor of the tableView to [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1]
I don't want to do this, it's still visible.
In short, what can I do to scroll the table even when I start the scrolling from the transparent section?
First you create a label with no text(or a view) such that it completely fills the cell. Then create a new label with your text and add this as a subview of the first view.

How to change the Title View of the navigation bar into some Custom View and fill the original size

I want to change the titleView of navigationBar with a regular text field. Then I want to set the textField size to fill the old "normal" titleView.
I can't seem to be able to do this in storyBoard. Dragging a text Field to the place where the navigation title View is doesn't work.
So I added stuff at
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
PO(self.navigationItem.titleView);
CGRect theFrame= self.navigationItem.titleView.frame;
self.navigationItem.titleView=self.searchBar;
//self.searchBar.frame = theFrame;
while (false);
...
It's working with one cached. That PO is a macro that print the content of the object. Turns out at viewDidAppear, self.navigationItem.titleView is null.
So while I can display the searchBar, I cannot make the searchBar "fill" it's space because I do not know the space is.
I prefer not to hard code it because you know, things may change in the future.
So what should I do?
I once saw codes where rather than setting the self.navigationItem.titleView, you would simply add subview to it. The problem with this approach even on viewDidAppear, self.navigationItem.titleView is 0.
I added these codes:
CGRect theFrame= self.navigationItem.titleView.frame;
CGRect theFrame2 = self.searchBar.frame;
CGRect theFrame3 = self.navigationController.navigationItem.titleView.frame;
And, I do not know how to nslog structure value, however, theFrame and theFrame3 are all 0
You can try this inside viewWillAppear:
UIView *customTitleView = [[UIView alloc]initWithFrame:CGRectMake((320-210)/2, 0, 210, 50)];
customTitleView.backgroundColor = [UIColor clearColor];
//create your UITextField or UILabel or other view and add as subview of customTitleView
self.navigationItem.titleView = customTitleView;

how to change the height of two views (One view shrink and the other expand) using objective c?

i have two views(A&B) in the same view controller(popOver window) and want to toggle between them, view A is larger than view B, when the popOver window first loads i want view A only to appear and when i press certain button inside it , it should shrink down to let view B appear above it, i tried to set the height of view B to fit into the all window when the window first load(Inside viewDidLoad)then reduce it's height and increase the height of the other view when a button is clicked, i try that code but it didn't change the height of the view !!
-(void)viewDidLoad
{
[super viewDidLoad];
UIView *contactsView=[self.view viewWithTag:2];// is this a correct initialization of a uiView from a view in a storyBoard ?
CGRect frame=contactsView.frame;
frame.size.height+=100;
contactsView.frame=frame;
}
any idea about that will be helpful,thanks.
As a general answer (I don't have time for more detail), I would use 3 views overall:
1) The view owned by your View Controller.
2) View A
3) View B
View A and B can be created in viewDidLoad of your view controller. Then set the frame of each of these for the position and size. Add them both to the view:
// in your .h file create these variable:
UIView* m_vA;
UIView* m_vB;
- (void)viewDidLoad
{
m_vA = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 50.0, 50.0)] autorelease];
m_vB = [[[UIView alloc] initWithFrame:<your rect for View B>] autorelease];
// The views will automatically be retained.
[self.view addSubview:vA];
[self.view addSubview:vB];
m_vB.hidden = YES;
}
// In your button callback, toggle the visibility of views
- (IBAction)buttonPressed:(id)sender
{
// Toggle the visibility of views
m_vA.hidden = !m_vA.hidden;
m_vB.hidden = !m_vB.hidden;
}
// Dont forget to clean up the memory of these views in dealloc and viewDidUnload.