xcode and storyboard: how build an user profile view - ios

how can i build an user profile view like this (Periscope but is similar to many other apps).
It's a tableviewcontroller? If it is, how can i put the image of the user with background (it's in the first cell or above the tableview?)

I'd build it this way:
UIViewController with UITableView + custom UIView on top.
If you want to use already implemented libraries, check this out :
MGSpotyViewController
jcbannerView
Facade
They have pretty similar logic that's described in your question.

It is a custom tableviewcontroller. Everything is a cell but it is hard to create only using storyboard. you create a dynamic table view and ad 3 prototype cell for it (1: Blue cell, 2:Grey empty cell, 3: Option Cell). And create a controller and manage the cell with it like:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexpath.row== 0)
{
HeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:#"headerCell" forIndexPath:indexPath];
cell.name = "foo";
....
}
else if(indexpath.row ==1 || indexpath.row ==3)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"blankCell" forIndexPath:indexPath];
[cell setBackgroundColor:[UIColor greyColor]];
}else{
....
}
}

Looks like above is a header view, and below a table view.
If the above part scrolls off it is the table view's tableHeaderView. In this case you can use a UITableViewController.
Otherwise you will have to use a UIViewController with a UIView as the header and a UITableView below it, and you have to declare the table view delegate and datasource yourself.

You can achieved same UI with help of bringing UITableView and add UIView with blue background as tableHeaderView like as below.
UIView *headerView = [[UIView alloc] init...];
tableView.tableHeaderView = headerView;

Related

IOS7 Custom TableViewCell will not appear

I am trying to create a project with a custom UITableViewCell. The custom cells never load, they're just blank. At this point in the project what I'm trying to do is placing a UITableViewCell in a .xib, designing it the way I want and specifying its reuse identifier along with tag IDs for the components so that I can use them in code later on.
I've googled a ton and found several tutorials that look like what I want to do, along with many SO questions that have answers that seem applicable. At this point it's probably just my head spinning with too many different angles and solutions.
This is my current attempt at trying to register the custom cell with my UITableView, yet when running this on a device the rows in the table view are entirely blank.
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
UILabel* l1 = (UILabel*)[cell viewWithTag:1];
UILabel* l2 = (UILabel*)[cell viewWithTag:2];
UILabel* l3 = (UILabel*)[cell viewWithTag:3];
l1.text = #"Foobar";
l2.text = #"Foobar";
l3.text = #"Foobar";
I'm pretty certain that I've hooked up all the properties and such correctly, but at this stage I need a fresh pair of eyes to point out the facepalm for me.
The interesting files are FilmerView.m/h/xib and the cell is in FilmerViewCell.xib. When running the app this TableView is in the second tab of the tab bar controller.
Project:
http://speedy.sh/WhhpP/test12.zip
I can't provide a full answer atm but look up the tableview method. registerNib:forCellReuseIdentifier:
Also, stop using that dequeue method. Use the one that includes the indexPath.
Then you don't have to check if the cell is nil afterwards.
EDIT
In viewDidLoad (or somewhere like that)...
UINib *cellNib = [UINib nibWithNibName:#"MyCustomCellXibFileName" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"CellIdentifier"];
Now in the table view datasource method...
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier" forIndexPath:indexPath];
// no need to check cell == nil.
// this method is guaranteed to return a non nil cell.
// if it doesn't then the program will crash telling you that you need to...
// register a class or nib (but we just did this in viewDidLoad) :D
// configure your cell here...
[self configureMyCell:(MyCustomCell *)cell atIndexPath:indexPath];
return cell;
}
- (void)configureMyCell:(MyCustomCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
cell.nameLabel.text = #"Hello, world";
}
Hope this helps.
Make sure that you have set datasource and delegate properties of your tableView.
Make sure that you have implemented (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method and it returns a positive value (>0).
Evaluate the following:
Is the ReuseIdentifier set in the XIB. See Properties Tab in Interface Builder on the right when selecting the cell.
Are the AutoresizingMasks set properly for the labels to be visible?
WrapModes: Which did you select? When having wrapmode WrapWord, is the font size too large for the text to be moved in the next line becoming invisible?
Set the background color of the UITableViewCellss content view to something else than white or transparent, as well as the background colors of the labels to see if the cell is even there.
Manually call numberOfRowsInSection on your table, pass the proper NSIndexPath identifying the target section and see if its greater 0 to confirm that the TableView even attempts to load the data, thus, the cells. ( Alternatively set a breakpoint in the method or do a NSLog. )
Do a NSLog in cellForRowAtIndexPath to confirm that the cell returned is not nil and the method is even called!

How can I make a Custom UITableViewCell top cell draw uniquely after reuse?

So I've made some custom table view cells and they draw correctly and look great, however once I scroll past the edge of the visible cells they start being reused, which is fine, except that when I scroll back the reused cells are still shown and don't redraw. Specifically all the cells look the same except for the top-most cell.
Pictures detailing the occurrence:
How I have this coded up, is when the cells get made if the indexPath.row is greater than 0 add an "overlap effect" which is just a gradient on a uiview placed underneath the custom drawing on the UITableViewCell's contentView.
This is how I add the overlap effect in the UITableViewController's tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"APostCell";
PostCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
CustomPost *aPost = [self.posts objectAtIndex:indexPath.row];
if (indexPath.row > 0) {
[cell addOverlap];
}
cell.postDateLabel.text = [aPost datePostedAsString];
return cell;
}
How would I implement this [cell removeOverlap]?
Try this
if (indexPath.row == 0) {
//remove overlap here
} else {
[cell addOverlap];
}
beacuse, except 1st cell all have overlap.On scrolling the reused cell have the overlap. So for first cell remove the overlap if present.
So after I posted the question I figured it out and, since I had the question and had previously not found any information on the subject figured I would share.
So whenever
PostCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]
is called, the table view either creates a new cell or reuses an old one. When a new cell is created and it is not the top cell (indexPath.row == 0) it adds the overlap to the UITableViewCell. And if it reuses the cell, that method still gets called, regardless what cell is being reused. So naturally once the cell created at the top is reused, the gradient view still gets added to cell.contentView and it stays there even when I'm reusing for the topmost cell again.
In fact adding the overlap view in this way will stack multiple overlap views into the same cell.
So what has to be done (if you intend to customize the cell appearance this way) is to remove the added views before each reuse of the cell. So you have to overwrite the custom tableviewcell's prepareForReuse method and do just that like so.
- (void) prepareForReuse {
[super prepareForReuse];
[self removeOverlap];
}
Be SURE the cell has the overlap view otherwise your app will break by trying to remove views not there. so have something like
- (void) removeOverlap {
if ([self.contentView.subviews count] > 1) {
//This method works based on the assumption [cell addOverlap] adds new view
//underneath existing views - like [self.contentView insertSubview:overlappedView atIndex:0];
[[self.contentView.subviews objectAtIndex:0] removeFromSuperview];
}
}

Cannot set properties on custom table view cell

I have a problem settings my view elements on a custom cell. The table cells appear in my tableView, but the properties do not set and thus only empty/blank cells appear.
The tableView is not a tableView controller, but only a tableView in a viewController.
I have the following files:
CustomCell.xib:
Here i use IB to build the custom cell by using a Table View Cell from object library with labels and images on. I set the Identifier as orderListCell. From this screen I ctrl+drag to create the outlets in customCell.h
CustomCell.h
Here I see all my IBOutlets as properties from above mentioned file
CustomCell.m
Here I leave as is
OrderListViewController.h
Here I import customCell.h and use protocols UITableViewDelegate, UITableViewDataSource
OrderListViewController.m
Here I set my tableView delegate and tableView dataSource to self. I also create an IBOutlet for my tableView from the Storyboard.
I use the following code to try and display my cells:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"orderListCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[CustomCell alloc] init];
}
cell.myLabel.text = #"aaaaaaaa"; //[[self.orders objectAtIndex:indexPath.row] objectForKey: #"tableNo"];
return cell;
}
I have simplified my code a bit to demonstrate that even setting the label to a simple string (#"aaaaaaaa") doesnt work. When I look at the objects in my debugger the cell does have all the properties from the IBOutlets and the cell does appear in my tableView, just the label.text = xxx does not seem to work.
I have looked at the following posts but either dont understand it properly or it does not work for me:
ios 7 customizing UITableViewCell's content view
Can't set properties in Custom UITableViewCell
Set label for a custom cell
Any help or advice would be greatly appreciated
cell = [[CustomCell alloc] init]; does not create your cell from the XIB, so none of the XIB content will be created.
Use registerNib:forCellReuseIdentifier: to register the XIB with the table view so that it will create your cell instances for you (you don't need to create instances yourself in cellForRowAtIndexPath).
If you don't want to do that, you can load your NIB explicitly with nibWithNibName:bundle: and instantiateWithOwner:options:, then get the cell instance from the list of returned views (which should only contain 1 item).

How do I have a UITableView with two different cell types and set each of the`cell layouts up programmatically, instead of via a Storyboard?

Previously I had this set up with a storyboard, having dragged the UILabels, positioned them and sized them whatnot on the UITableViewCell I dragged them onto, and then do a different version of that for the other UITableViewCell.
For example, like follows (but in the picture they've yet to be customized with the labels):
Then in the datasource, I'd simply check the Identifier, and depending on what the Identifier was, customize the cell accordingly.
However, I've needed more customization than I can get from the storyboard, as each cell is going to have two UIViews (a top one and a bottom one to allow sliding of the top one) so I can't really do this with storyboarding, as I add the labels and everything to the UIView programmatically.
But my question is: When I do it programmatically, how can I tell which cell is which so I can customize the layout of the UILabels accordingly? With a storyboard I can obviously just drag a UILabel onto each one, but when doing it programmatically and setting up the UIView, I don't know how to say, "Hey, if the identifier is this, add the UILabels like so" because the UIViews aren't aware of any Identifiers.
Basically the structure looks like this:
UITableView -> UITableViewCell -> CellFront(UIView) & CellBack(UIView)
And the look of the cell comes from the labels added to the CellFront UIView. But there's two looks to the cells and I don't know how to do it without a storyboard.
Although UIViews are not aware of identifiers, they have a property called tag which can be used for any purpose that you would like. You can set the tag to, say, 1 on cells of one kind, and to 2 on cells of the other kind, and then use the tag to distinguish the cells in code. Moreover, once your views are tagged, you can call viewWithTag: on the containing view, and get back the view with the tag that you want.
If you are creating the cells solely in code, then you register your UITableViewCell subclass in the viewDidLoad method of your table view controller. That method sets the identifier. Then, you use that identifier in cellForRowAtIndexPath: just like you would for a xib or storyboard created cell.
[self.tableView registerClass:[MyCellSubclass class] forCellReuseIdentifier:#"MyIdentifier"];
Here is one approach:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Adjust the condition to match your needs
if (indexPath.row == 0) {
static NSString *Identifier1 = #"CellType1";
// cell type 1
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier1];
// add subviews here
}
// set cell properties
return cell;
} else {
static NSString *Identifier1 = #"CellType2";
// cell type 2
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier2];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier2];
// add subviews here
}
// set cell properties
return cell;
}
}

Image on top of Cell

Can i put an image in the top of an TableViewCell instead of putting it on the left side ? I used this to put it in the cell:
Code:
cell.imageView.image = [UIImage imagenNamed:#"river.png"];
For asynchronous image downloading and showing on table use this:
go to https://github.com/enormego/EGOImageLoading
and download the classes.
then in your .h file:
#class EGOImageView;
EGOImageView *imageIconView; // object for caching the images
and in .m file
#import "EGOImageView.h"
#import "EGOCache.h"
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
imageIconView=[[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:#"icon72x72.png"]];
[self setFlickrPhoto:[NSString stringWithFormat:#"yourimageurl"];
imageIconView.frame=CGRectMake(0, 0, 120, 100);
[cell addSubview:imageIconView];
return cell;
}
- (void)setFlickrPhoto:(NSString*)flickrPhoto
{
imageIconView.imageURL = [NSURL URLWithString:flickrPhoto];
}
You can create a custom cell. You just pick style custom for the cell type. If you are using static cells you can just insert an ImageView in the cell, drag an outlet to the controller header file and set the image in the code.
If you are using dynamic cells its best to create a new class for your cells. Set the custom class for the cell in the interface builder. Create and outlet for the imageview in the custom cell class header. Then when you instantiate cells in the tableView:cellForRowAtIndexPath, set the cell class to the custom cell class and set its property.
There are very good tutorials for storyboards that cover dynamic and static cell tables:
Beginning Storyboards in iOS Part 1
Beginning Storyboards in iOS Part 2
you have set the frame of an imageview in cellforRowAtIndexPath
Yes you can. for this you have to go for custom tableview cell. you can design this using separate XIB for tableview cell. May be this link will help you.
or search on google also for more examples its easy to implement.

Resources