I'm new on IOS development and I'm working on Ipad app for News Blog and I want to create Home screen look like this :
So my question is what's the best way to do that?
I mean, Should I create reusable view ( two views : one for the big size
post and the second for the small size post), then I add those view to my UIViewController in storyboard.
Or, create one reusable view with the big size and when I added it to storyboard I resize it (I'm not sure if this solution can be achieved and create UIview with dynamic size )?
Or, I create those view directly in my storyBoard and no need for using reusable component ?
Update
Thank's To Larme solution I've used UIcollectionView. But the problem I can't push the two first small row, in red circle, to top of screen and add under them two other small Cell
I want to have 4 small cells on the right big cell
This is my code:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize imgSize = CGSizeMake(230, 160);
if (indexPath.row == 0) {
//double the size for the first cell
imgSize = CGSizeMake(490, 360);
}
return imgSize;
}
-(UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(5, 5, 5, 5);
}
Related
Basically I'm trying to find an iOS library (Obj-C is preferred) for a custom view described below. I wasn't able to find something similar but still it looks like this is pretty common view so maybe anybody from the community can point me to the right place.
So I'm trying to implement a view in iOS to replicate behavior from the image:
Basically it's a horizontal container view which stacks other views (basically UILabels) based on their width and dynamically adds more rows when required.
So my current approach on a high level is to implement it as the following:
to pass a list of NSStrings into the container view
container view will create UILabels for every string
It then calculates width for every label and total widths of all labels
container view dynamically calculates number of items for the current row based on container's width.
The rest items comes to the next row (container height increases) and step 4 repeats while there are unprocessed UILabels in the queue.
While the process is rather straightforward I'm still trying to find possible ways to simplify the development and to save client's budget on this feature.
So maybe someone can point a better approach? Seems like UICollectionView can be a good alternative but still maybe there are any libraries which do something similar to what I've described above?
Couldn't find anything on github but probably it's just because I'm searching it incorrectly.
Code work
- (IBAction)actionTagCancel:(UIButton *)sender {
[arrTagList removeObjectAtIndex:sender.tag];
[self.collecTagCategory reloadData];
}
#pragma mark- collection data source
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return arrTagList.count;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize tagLabelSize = [arrTagList[indexPath.row] boundingRectWithSize: CGSizeMake(self.view.frame.size.width-75, 120)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont fontWithName:#"Helvetica Neue" size:14.0 ]}
context:nil].size;
return CGSizeMake (tagLabelSize.width + 45, 30);
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
TagViewListCell *tagCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"tagCell" forIndexPath:indexPath];
tagCell.viewTag.layer.cornerRadius = 4;
tagCell.btnTagCancel.tag = indexPath.row;
tagCell.lblTagName.text = arrTagList[indexPath.row];
_constTagViewHeight.constant = _collecTagCategory.contentSize.height;
return tagCell;
}
Output
Automatic manageable after deletion of tag
Edit
Get Repository of project from here
Here is my problem: I'm developing a Kodi Remote on iOS (http://forum.kodi.tv/showthread.php?tid=235973) and everything run pretty well (a classic development) but I'm having a behavior that I can't explain.
I have multiple view controllers; in one of them (a UIViewController containing a UICollectionView), I implemented this delegate method :
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGSize originalSize = [(UICollectionViewFlowLayout *)collectionViewLayout itemSize];
CGSize collectionViewSize = [collectionView frame].size;
CGFloat interItemSpacing = [(UICollectionViewFlowLayout *)collectionViewLayout minimumInteritemSpacing];
UICollectionViewFlowLayout *collectionViewFlowLayout = (UICollectionViewFlowLayout *)[[self collectionView] collectionViewLayout];
UIEdgeInsets sectionInset = [collectionViewFlowLayout sectionInset];
CGFloat usableWidth = (collectionViewSize.width - ((kColumns - 1) * interItemSpacing) - sectionInset.left - sectionInset.right);
CGFloat width = usableWidth / kColumns;
CGFloat height = width * originalSize.height / originalSize.width;
return CGSizeMake(width, height);
}
I get the collection view frame (bounds is the same, of course, I don't need origin) and it works great. I get on an iPhone 5 simulator 288 width for a no matter height.
BUT, in a copy-paste of the view controller in the storyboard, I get a 304 width. The weirdest behavior is that with FLEX, and after the render, the collection view measures 288 pixels.
The "only" difference is that the first view controller is just pushed, the second is contained in a UITabBarController.
PS : the first screen I'm talking about are the 3rd & 4th screenshots.
If someone has an explication to this, I'll take it ;)
Update 1 :
If I invalidate the collection view layout in - (void)viewDidLayoutSubviews, items are correctly drawn BUT there is like a flash because the whole collection view is redrawn (the header & items below).
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(self.collectionView.frame.size.width,
self.collectionView.frame.size.height);
}
and uncheck "Constrain to margins" and click on all dotted red constrain
so -8 padding will be gone in iPhone 6+
Storyboard
It makes a lot of sense when you approach the problem with a Storyboard. First, you will get a clear view of what you are designing. Second, you get to build your application with exactly 0 lines of code, leading to 0 bugs.
The parent UITabBarController and a set of UINavigationController is a common design pattern, and only when you implement it as follow do you get a proper UI behavior.
Code
You do not have to use a Storyboard to create the hierarchy above. You can embed each UIViewController in a UINavigationController programatically.
► Find this solution on GitHub and additional details on Swift Recipes.
All,
I have a View Controller with a UICollectionView , and the UICollection has a collection of small images (35x35) to make a grid. I am using an inferred size of VC. I have set the top, bottom, left and right constraints..
The problem is that on the iPhone 6 the amount of cells are correct, but obviously on a iPhone 5 and iPhone 4 there is a smaller amount vertically.
How did I get it so that there is an exact amount of cells vertically on all devices ?
I am not familiar with swift, but i hope that this objective-c explanation helps:
In your -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath method you can specify the width and height of your cell.
for example if you only want 2 cells per row and 3 per column user this:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screen = [[UIScreen mainScreen]bounds];
return CGSizeMake(screen.size.width/2 - YourHorizontalPadding, screen.size.height/3- YourVerticalPadding);
}
The vertical and horizontal padding is the space you have between your cells, you will have to tweak them to get the desired result.
Hope that helps, let me know if something is not clear.
i already display the image as grid view using UICollectionView with equal size like follows
Next step i want to display cell as different size but the images fit into the that cell like this
this need to be work in the storyboard because other functions done in the storyboard so somebody help me..
In your collection view controller add:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//return the size of the cell based on image size or other criteria
}
Add constraints to the image:
Here's a simple UICollectionView in yellow
The red arrow sets the width of the cell. (TBC: clicking on the pink cell: for 'size' select 'Default', then what you set at the red arrow becomes the size of the cell.)
Example, for an upright iPhone set width to 320.
But this seems crazy ... surely I can set the cell width based on the width of the UICollectionView?
There's no problem autosizing the view itself ..
That works fine.
But it seems crazy that I can't set the width of the CELL to be "same as the view". It seems hard to believe one has to set it manually, in code?
TBC In other words, as Nikita points out,
-(CGSize) collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return self.view.frame.size;
}
(indeed you also typically need this ...)
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0,0,0,0); //t,l,b,r
}
In fact - you have to do that in code?! There's no way to do that in Storyboard, with autolayout, or anything else?!
I think you need to take a look at
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
of UICollectionViewLayout where you can set size based on orientation and current frame.
It would indeed seem that you simply have to do this in code.
There is a simple way to do this. Here is the swift code. Assumes you want one item wide and in the example my cells are 64 pts high, and I want 8 pts for side margins, and finally collectionView is the name of your UICollectionView.
Insert this into viewDidLoad :
let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize.init(width: (UIScreen.main.bounds.width - 16), height: 64.0)
This will set all the cells to default to that size. You can still override individual cells if you subclass UICollectionViewLayout or UICollectionViewFlowLayout, as mentioned in other answers. But if you simply want to have more table view like behavior this should work.
I my case cell inset making extra shapes