I am new to iOS development and this is my first project that i am doing alone. i am trying to show the feed of my college's unofficial fb page using uicollectionview. I have been trying a lot of different things but nothing seems to work.
UICollectionViewController.m file
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"DCE Speaks Up";
self.collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = NO;
NSError *error= nil;
NSURL *feedURL = [NSURL URLWithString:#"https://graph.facebook.com/382057938566656/feed?fields=id,full_picture,message,story,created_time,link&access_token=1750413825187852%7CkUl9nlZFPvdGxGZX4WYabKKG2G4"];
NSData *jsonData = [NSData dataWithContentsOfURL:feedURL];
NSDictionary *dataDictionary= [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.feedArray = [NSMutableArray array];
NSArray *feedTempArray = [dataDictionary objectForKey:#"data"]; //feedTempArray just used for parsing
for (NSDictionary *feedDictionary in feedTempArray) {
FacebookFeed *fbFeed =[FacebookFeed facebookFeedWithMessage:[feedDictionary objectForKey:#"message"]];
fbFeed.story = [feedDictionary objectForKey:#"story"];
fbFeed.imageURL = [NSURL URLWithString:[feedDictionary objectForKey:#"full_picture"]];
fbFeed.date = [feedDictionary objectForKey:#"created_time"];
fbFeed.sharedLink = [NSURL URLWithString:[feedDictionary objectForKey:#"link"]];
[self.feedArray addObject:fbFeed];
}
// Register cell classes
[self.collectionView registerClass:[FacebookCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
// Do any additional setup after loading the view.
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FacebookCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.feed = self.feedArray[indexPath.row];
cell.sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
// Configure the cell
for (UIView *view in cell.contentView.subviews) {
if ([view isKindOfClass:[UILabel class]]) {
[view removeFromSuperview];
}else if ([view isKindOfClass:[UIImageView class]]){
[view removeFromSuperview];
}
}
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
#pragma mark <UICollectionViewDelegateFlowLayout>
-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *sizeDictionary = [[NSDictionary alloc] init];
sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
return CGSizeMake(self.view.frame.size.width - 20, [sizeDictionary[#"imageHeight"] floatValue] + [sizeDictionary[#"messageHeight"] floatValue] + [sizeDictionary[#"nameHeight"] floatValue]);
}
#pragma mark <UICollectionViewDelegate>
- (NSDictionary *) sizeForLabelAtIndexPath:(NSUInteger)indexPath collectionView:(UICollectionView *)collectionView{
FacebookFeed *feed = self.feedArray[indexPath];
CGSize nameSize = CGSizeFromString(#"DCE Speaks Up");
CGSize imageSize = CGSizeMake(0, 0);
if (feed.imageURL) {
imageSize = CGSizeMake(470, 394);
}
float height = 80;
NSString *string = #"";
if (feed.message) {
string = [feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}else if (feed.story){
string = [feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if (string) {
NSDictionary *attributes = #{
NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
};
CGRect bodyFrame =
[string boundingRectWithSize:CGSizeMake(CGRectGetWidth(collectionView.bounds),
CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin)
attributes:attributes
context:nil];
height += ceilf(CGRectGetHeight(bodyFrame));
}
return #{ #"imageHeight" : #(imageSize.height) , #"messageHeight" : #(height) , #"nameHeight" : #(nameSize.height)};
}
Custom cell file
#implementation FacebookCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self)
{
self.contentView.backgroundColor = [UIColor whiteColor];
// change to our custom selected background view
self.imageView = [[UIImageView alloc] init];
self.messageLabel = [[UILabel alloc] init];
self.nameLabel = [[UILabel alloc] init];
}
return self;
}
-(void) setFeed:(FacebookFeed *)feed{
_feed = feed;
self.messageLabel.numberOfLines = 0;
self.messageLabel.lineBreakMode = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data= [NSData dataWithContentsOfURL:feed.imageURL];
UIImage *theImage=[UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image= theImage ;
});
});
if (feed.message) {
self.messageLabel.text = [[NSString alloc] initWithString:[feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}else{
self.messageLabel.text = [[NSString alloc] initWithString:[feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
self.messageLabel.font = [UIFont fontWithName:#"ArialMT" size:11];
[self.messageLabel sizeToFit];
self.nameLabel.text = #"DCE Speaks Up";
[self.nameLabel setFont:[UIFont fontWithName:#"ArialMT" size:12]];
[self.nameLabel sizeToFit];
}
-(void) layoutSubviews{
NSLog(#"%#",self.feed);
self.nameLabel.frame = CGRectMake(10, 10, self.contentView.bounds.size.width, [self.sizeDictionary[#"nameHeight"] floatValue]);
float height = 200;
if (self.contentView.bounds.size.height - [self.sizeDictionary[#"messageHeight"] floatValue] -[self.sizeDictionary[#"nameHeight"] floatValue] >100) {
height = self.contentView.bounds.size.height - [self.sizeDictionary[#"messageHeight"] floatValue] -[self.sizeDictionary[#"nameHeight"] floatValue];
}
if (self.feed.imageURL) {
self.imageView.frame = CGRectMake(10, [self.sizeDictionary[#"messageHeight"] floatValue] +[self.sizeDictionary[#"nameHeight"] floatValue], self.contentView.bounds.size.width - 20,height);
self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[#"nameHeight"] floatValue] +10, self.contentView.bounds.size.width - 10, [self.sizeDictionary[#"messageHeight"] floatValue]);
[self.contentView addSubview:self.messageLabel];
[self.contentView addSubview:self.imageView];
}else{
self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[#"nameHeight"] floatValue], self.contentView.bounds.size.width - 10, [self.sizeDictionary[#"messageHeight"] floatValue]);
[self.contentView addSubview:self.messageLabel];
}
[self.contentView addSubview:self.nameLabel];
}
#end
Use NSLayoutConstraints, it's the standard and best practice. Also you shouldn't be adding subviews in layoutSubviews(), as this method may get called multiple times. I'd also suggest moving your cell size calculation code into your UICollectionViewCell subclass.
There is a lot of odd stuff going on in your code, so it's hard to tell what's causing your problems. It's probably a combination of all of the subview adding/removing and manual size calculations. You could also use the visual debugger to give you some clues as to what might be happening:
https://www.raywenderlich.com/98356/view-debugging-in-xcode-6
I believe your problem is here:
-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *sizeDictionary = [[NSDictionary alloc] init];
sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
return CGSizeMake(self.view.frame.size.width - 20, [sizeDictionary[#"imageHeight"] floatValue] + [sizeDictionary[#"messageHeight"] floatValue] + [sizeDictionary[#"nameHeight"] floatValue]);
}
You set in CGSizeMake width:
self.view.frame.size.width - 20
And height:
[sizeDictionary[#"imageHeight"] floatValue] + [sizeDictionary[#"messageHeight"] floatValue] + [sizeDictionary[#"nameHeight"] floatValue]
Check it out if the size of your height it's correct. It looks like is too big. That method return the size of the each cell. I believe you have been setting a bigger height than you want to.
Related
I try a adding UITableView into scrollview programmatically. I have set anchors and datasource, delegate. You can see in codes. But I can't. I put a breakpoint and everything run. But I can't see in my scrollview.
UITableView *tableView = [[UITableView alloc] init];
tableView.rowHeight = 130;
tableView.translatesAutoresizingMaskIntoConstraints = false;
tableView.delegate = self;
tableView.dataSource = self;
tableView.backgroundColor = [UIColor clearColor];
[self.scrollView addSubview:tableView];
[tableView.leftAnchor constraintEqualToAnchor:self.scrollView.leftAnchor constant:8].active = YES;
[tableView.rightAnchor constraintEqualToAnchor:self.scrollView.rightAnchor constant:8].active = YES;
[tableView.topAnchor constraintEqualToAnchor:self.viewShareBasketExtra.topAnchor constant:8].active = YES;
[tableView reloadData];
This codes are working:
UILabel *lblPrice = [[UILabel alloc] init];
[lblPrice setFont:[UIFont fontWithName:#"HelveticaNeue" size:14]];
lblPrice.translatesAutoresizingMaskIntoConstraints = false;
[lblPrice setTextAlignment:NSTextAlignmentCenter];
lblPrice.text = [NSString stringWithFormat:#"%.2f TL",[_productModel Price]];
[self.priceView addSubview:lblPrice];
[lblPrice.leftAnchor constraintEqualToAnchor:self.priceView.leftAnchor constant:8].active = YES;
[lblPrice.rightAnchor constraintEqualToAnchor:self.priceView.rightAnchor constant:8].active = YES;
[lblPrice.centerXAnchor constraintEqualToAnchor:self.priceView.centerXAnchor].active = YES;
[lblPrice.centerYAnchor constraintEqualToAnchor:self.priceView.centerYAnchor].active = YES;
[self getComments];
But that codes are not working :
UITableView *tableView = [[UITableView alloc]init];
tableView.rowHeight = 130;
tableView.translatesAutoresizingMaskIntoConstraints = false;
tableView.delegate = self;
tableView.dataSource = self;
tableView.backgroundColor = [UIColor clearColor];
[self.scrollView addSubview:tableView];
[tableView.leftAnchor constraintEqualToAnchor:self.scrollView.leftAnchor constant:8].active = YES;
[tableView.rightAnchor constraintEqualToAnchor:self.scrollView.rightAnchor constant:8].active = YES;
[tableView.topAnchor constraintEqualToAnchor:self.webView.topAnchor constant:8].active = YES;
My delegate methods :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(commentsArray!=nil){
return [commentsArray count];
}else
{
return 0;
}
}
And I am using custom table cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identity = #"CommentTableViewCell";
CommentTableViewCell *cell = (CommentTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identity];
if(cell == nil){
#try {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CommentTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
#catch (NSException *exception) {
NSLog(#"Err:%#", exception.reason);
}
#finally {
}
}
in your header file .h add the next code:
<UITableViewDelegate,UITableViewDataSource>
For example in UIVIewController Class
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
and this is all for you header file now got to .m and implement de nextlines:
this is for height:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{return 40.0f}
and after for this you add in your scrollview
scrollview.addSubview(yourTableView)
didLoad, now UILabel *lblPrice = [[UILabel alloc] init]; working but _webView = [[UIWebView alloc] init]; not working.
- (void)viewDidLoad {
[super viewDidLoad];
self.leftLabel = 0;
self.topLabel = 0;
self.statusWeb = 0;
[self.scrollView setBackgroundColor:[UIColor redColor]];
[lblFavoritesComment setText:[NSString stringWithFormat:#"%ld",(long)[_productModel totalFavorite]]];
[lblCommentCount setText:[NSString stringWithFormat:#"%ld",(long)[_productModel totalComments]]];
[lblProductName setText:[_productModel ProductName]];
lblDescription.lineBreakMode = UILineBreakModeWordWrap;
lblDescription.numberOfLines = 0;
[lblDescription setText:[_productModel Description]];
[lblDescription sizeToFit];
if([_productModel serviceHour] == 0){
NSString *serviceMinStr = [NSString stringWithFormat:#"%ld dk.",(long)[_productModel serviceMin]];
[lblTime setText:serviceMinStr];
}
if([_productModel serviceHour ] == 0 && [_productModel serviceMin] == 0){
[lblTime setText:#""];
}
if(![_productModel.Recipe isKindOfClass:[NSNull class]]){
if(![_productModel.Recipe isEqualToString:#"NULL"] || _productModel.Recipe.length>0){
self->statusWeb = 1;
_webView = [[UIWebView alloc] init];
_webView.translatesAutoresizingMaskIntoConstraints = false;
_webView.frame = CGRectMake(0,0,200, 300);
NSMutableString *html = [NSMutableString stringWithString: #"<html><head><title></title></head><body style=\"background:transparent;\">"];
[html appendString:[_productModel Recipe]];
[html appendString:#"</body></html>"];
[_webView setBackgroundColor:[UIColor blueColor]];
[_webView loadHTMLString:[html description] baseURL:nil];
[self.viewWebView addSubview:_webView];
[_webView.topAnchor constraintEqualToAnchor:self.viewShareBasketExtra.topAnchor constant:10].active = YES;
[_webView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:8].active = YES;
[_webView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:8].active = YES;
}
}else{
}
int multiPriceStatus = (int)[_productModel multiPrice];
if(multiPriceStatus == 1){
[self getMultiPrice];
}else{
UILabel *lblPrice = [[UILabel alloc] init];
[lblPrice setFont:[UIFont fontWithName:#"HelveticaNeue" size:14]];
lblPrice.translatesAutoresizingMaskIntoConstraints = false;
[lblPrice setTextAlignment:NSTextAlignmentCenter];
lblPrice.text = [NSString stringWithFormat:#"%.2f TL",[_productModel Price]];
[self.priceView addSubview:lblPrice];
[lblPrice.leftAnchor constraintEqualToAnchor:self.priceView.leftAnchor constant:8].active = YES;
[lblPrice.rightAnchor constraintEqualToAnchor:self.priceView.rightAnchor constant:8].active = YES;
[lblPrice.centerXAnchor constraintEqualToAnchor:self.priceView.centerXAnchor].active = YES;
[lblPrice.centerYAnchor constraintEqualToAnchor:self.priceView.centerYAnchor].active = YES;
[self getComments];
}
NSString *photo = [_productModel ProductImage];
photo = [photo stringByAddingPercentEscapesUsingEncoding : NSUTF8StringEncoding];
[imgProduct setShowActivityIndicatorView:YES];
[imgProduct setIndicatorStyle:UIActivityIndicatorViewStyleGray];
[imgProduct sd_setImageWithURL:[NSURL URLWithString:photo]
placeholderImage:[UIImage imageNamed:#"placeholder"] options:/* DISABLES CODE */ (0) == 0 ? SDWebImageRefreshCached : 0];
[imgProduct setContentMode:UIViewContentModeScaleAspectFit];
QewerFavoriteGesture *favoriteGesture = [[QewerFavoriteGesture alloc] initWithTarget:self action:#selector(addFavorite:)];
favoriteGesture.productId = [_productModel Id];
favoriteGesture.numberOfTapsRequired = 1;
[imgFavorite setUserInteractionEnabled:YES];
[imgFavorite addGestureRecognizer:favoriteGesture];
QewerFavoriteGesture *basketGesture = [[QewerFavoriteGesture alloc] initWithTarget:self action:#selector(showBasketWindow:)];
basketGesture.productId = [_productModel Id];
basketGesture.numberOfTapsRequired = 1;
[imgBasket setUserInteractionEnabled:YES];
[imgBasket addGestureRecognizer:basketGesture];
QewerFavoriteGesture *extraGesture = [[QewerFavoriteGesture alloc] initWithTarget:self action:#selector(openExtras:)];
extraGesture.productId = [_productModel Id];
extraGesture.numberOfTapsRequired = 1;
[imgExtra setUserInteractionEnabled:YES];
[imgExtra addGestureRecognizer:extraGesture];
QewerFavoriteGesture *commentGesture = [[QewerFavoriteGesture alloc] initWithTarget:self action:#selector(openComments:)];
commentGesture.productId = [_productModel Id];
commentGesture.numberOfTapsRequired = 1;
[lblCommentCount setUserInteractionEnabled:YES];
[lblCommentCount addGestureRecognizer:commentGesture];
}
I am new to iOS development and this is my first project that i am doing alone. i am trying to show the feed of my college's unofficial fb page using uicollectionview. I have been trying a lot of different things but nothing seems to work. The uilabel for the name is not being added to the collection view. However before i added the sizeForLabelAtIndexPath method which is to determine the size of the 2 ui labels and the height of the image to be displayed, the name label was working fine
UICollectionViewController.m file
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"DCE Speaks Up";
self.collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = NO;
NSError *error= nil;
NSURL *feedURL = [NSURL URLWithString:#"https://graph.facebook.com/382057938566656/feed?fields=id,full_picture,message,story,created_time,link&access_token=1750413825187852%7CkUl9nlZFPvdGxGZX4WYabKKG2G4"];
NSData *jsonData = [NSData dataWithContentsOfURL:feedURL];
NSDictionary *dataDictionary= [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.feedArray = [NSMutableArray array];
NSArray *feedTempArray = [dataDictionary objectForKey:#"data"]; //feedTempArray just used for parsing
for (NSDictionary *feedDictionary in feedTempArray) {
FacebookFeed *fbFeed =[FacebookFeed facebookFeedWithMessage:[feedDictionary objectForKey:#"message"]];
fbFeed.story = [feedDictionary objectForKey:#"story"];
fbFeed.imageURL = [NSURL URLWithString:[feedDictionary objectForKey:#"full_picture"]];
fbFeed.date = [feedDictionary objectForKey:#"created_time"];
fbFeed.sharedLink = [NSURL URLWithString:[feedDictionary objectForKey:#"link"]];
[self.feedArray addObject:fbFeed];
}
// Register cell classes
[self.collectionView registerClass:[FacebookCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
// Do any additional setup after loading the view.
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FacebookCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.feed = self.feedArray[indexPath.row];
cell.sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
// Configure the cell
for (UIView *view in cell.contentView.subviews) {
if ([view isKindOfClass:[UILabel class]]) {
[view removeFromSuperview];
}else if ([view isKindOfClass:[UIImageView class]]){
[view removeFromSuperview];
}
}
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
#pragma mark <UICollectionViewDelegateFlowLayout>
-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *sizeDictionary = [[NSDictionary alloc] init];
sizeDictionary = [self sizeForLabelAtIndexPath:indexPath.row collectionView:collectionView];
return CGSizeMake(self.view.frame.size.width - 20, [sizeDictionary[#"imageHeight"] floatValue] + [sizeDictionary[#"messageHeight"] floatValue] + [sizeDictionary[#"nameHeight"] floatValue]);
}
#pragma mark <UICollectionViewDelegate>
- (NSDictionary *) sizeForLabelAtIndexPath:(NSUInteger)indexPath collectionView:(UICollectionView *)collectionView{
FacebookFeed *feed = self.feedArray[indexPath];
CGSize nameSize = CGSizeFromString(#"DCE Speaks Up");
CGSize imageSize = CGSizeMake(0, 0);
if (feed.imageURL) {
imageSize = CGSizeMake(470, 394);
}
float height = 80;
NSString *string = #"";
if (feed.message) {
string = [feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}else if (feed.story){
string = [feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if (string) {
NSDictionary *attributes = #{
NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody]
};
CGRect bodyFrame =
[string boundingRectWithSize:CGSizeMake(CGRectGetWidth(collectionView.bounds),
CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin)
attributes:attributes
context:nil];
height += ceilf(CGRectGetHeight(bodyFrame));
}
return #{ #"imageHeight" : #(imageSize.height) , #"messageHeight" : #(height) , #"nameHeight" : #(nameSize.height)};
}
Custom cell file
#implementation FacebookCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self)
{
self.contentView.backgroundColor = [UIColor whiteColor];
// change to our custom selected background view
self.imageView = [[UIImageView alloc] init];
self.messageLabel = [[UILabel alloc] init];
self.nameLabel = [[UILabel alloc] init];
}
return self;
}
-(void) setFeed:(FacebookFeed *)feed{
_feed = feed;
self.messageLabel.numberOfLines = 0;
self.messageLabel.lineBreakMode = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data= [NSData dataWithContentsOfURL:feed.imageURL];
UIImage *theImage=[UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image= theImage ;
});
});
if (feed.message) {
self.messageLabel.text = [[NSString alloc] initWithString:[feed.message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}else{
self.messageLabel.text = [[NSString alloc] initWithString:[feed.story stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
self.messageLabel.font = [UIFont fontWithName:#"ArialMT" size:11];
[self.messageLabel sizeToFit];
self.nameLabel.text = #"DCE Speaks Up";
[self.nameLabel setFont:[UIFont fontWithName:#"ArialMT" size:12]];
[self.nameLabel sizeToFit];
}
-(void) layoutSubviews{
NSLog(#"%#",self.feed);
self.nameLabel.frame = CGRectMake(10, 10, self.contentView.bounds.size.width, [self.sizeDictionary[#"nameHeight"] floatValue]);
float height = 200;
if (self.contentView.bounds.size.height - [self.sizeDictionary[#"messageHeight"] floatValue] -[self.sizeDictionary[#"nameHeight"] floatValue] >100) {
height = self.contentView.bounds.size.height - [self.sizeDictionary[#"messageHeight"] floatValue] -[self.sizeDictionary[#"nameHeight"] floatValue];
}
if (self.feed.imageURL) {
self.imageView.frame = CGRectMake(10, [self.sizeDictionary[#"messageHeight"] floatValue] +[self.sizeDictionary[#"nameHeight"] floatValue], self.contentView.bounds.size.width - 20,height);
self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[#"nameHeight"] floatValue] +10, self.contentView.bounds.size.width - 10, [self.sizeDictionary[#"messageHeight"] floatValue]);
[self.contentView addSubview:self.messageLabel];
[self.contentView addSubview:self.imageView];
}else{
self.messageLabel.frame = CGRectMake(10, [self.sizeDictionary[#"nameHeight"] floatValue], self.contentView.bounds.size.width - 10, [self.sizeDictionary[#"messageHeight"] floatValue]);
[self.contentView addSubview:self.messageLabel];
}
[self.contentView addSubview:self.nameLabel];
}
#end
According to some answers I found in Stackoverflow, I should use this piece of code:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.collectionView scrollToItemAtIndexPath:selectedRow atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
but the scrolling freezes, so I have to set it up this way:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = [NSString stringWithString:barTitle];
self.automaticallyAdjustsScrollViewInsets = NO;
//Download JSON
NSError *error=nil;
NSURL *url = [NSURL URLWithString:urlToFollow];
data = [NSMutableData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *response = [dictionary objectForKey:#"items"];
articlesArray = [[NSArray alloc] initWithArray:response];
//sizes
CGFloat window_height = ([self window_height]-70.0);
CGFloat window_width = [self window_width];
CGRect frame = CGRectMake((window_width/2)-15.0f , window_height, 30.0f , 15.0f);
self.pageControl = [[UIPageControl alloc]initWithFrame:frame];
UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = self.collectionView.frame.size;
// Add a target that will be invoked when the page control is changed by tapping on it
[self.pageControl
addTarget:self
action:#selector(pageControlChanged:)
forControlEvents:UIControlEventValueChanged
];
// Set the number of pages to the number of pages in the paged interface
// and let the height flex so that it sits nicely in its frame
if (articlesArray.count >8) {
self.pageControl.numberOfPages = 10;
}else if (articlesArray.count <8){
self.pageControl.numberOfPages =[articlesArray count];
}
self.pageControl.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.pageControl];
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.collectionView scrollToItemAtIndexPath:selectedRow atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
#pragma mark uicollectionview
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [articlesArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
LOArcticlesCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
[cell.imageView setImageWithURL:[NSURL URLWithString:[[articlesArray objectAtIndex:indexPath.row]objectForKey:#"photoUrl"]]placeholderImage:[UIImage imageNamed:#"simboloLakari29.png"]];
index= indexPath.row;
cell.lblMake.text = [NSString stringWithString:[[articlesArray objectAtIndex:indexPath.row]objectForKey:#"marca"]];
cell.lblMake.lineBreakMode = NSLineBreakByWordWrapping;
cell.lblModel.text = [NSString stringWithString:[[articlesArray objectAtIndex:indexPath.row]objectForKey:#"modelo"]];
cell.lblModel.lineBreakMode = NSLineBreakByWordWrapping;
cell.lblPrice.text = [NSString stringWithString:[[articlesArray objectAtIndex:indexPath.row]objectForKey:#"precio"]];
cell.lblOrder.text = [NSString stringWithFormat:#"%ld de %ld", (unsigned long)indexPath.row+1, (unsigned long)articlesArray.count];
return cell;
}
#pragma mark page control
- (void)pageControlChanged:(id)sender
{
UIPageControl *pageControl = sender;
CGFloat pageWidth = self.collectionView.frame.size.width;
CGPoint scrollTo = CGPointMake(pageWidth * pageControl.currentPage, 0);
[self.collectionView setContentOffset:scrollTo animated:YES];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = self.collectionView.frame.size.width;
self.pageControl.currentPage = self.collectionView.contentOffset.x / pageWidth;
}
- (CGFloat) window_height {
return [UIScreen mainScreen].applicationFrame.size.height;
}
- (CGFloat) window_width {
return [UIScreen mainScreen].applicationFrame.size.width;
}
But the CollectionView goes from index=0 to the desired index and it's very annoying.
Any suggestion?
Im trying to make dynamic uitableviewcell height for my custome cell.
the cell is subclassed for adding some background.
this is my uitableview controller class :
#define PADDING 23.0f
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger count = [self.entries count];
return count + _rowcount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier = #"PlaceholderCell2";
SubcategoryTableViewCell * sctvCell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (sctvCell == nil) {
sctvCell= [[SubcategoryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
NSUInteger nodeCount = [self.entries count];
sctvCell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *label = (UILabel *)[sctvCell.contentView viewWithTag:1];
if (nodeCount > 0)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
[label setText:appRecord.title];
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"B MyFont" size:14.0f]};
CGRect rect = [appRecord.title boundingRectWithSize:CGSizeMake(label.frame.size.height - PADDING * 5, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGRect newFrame = label.frame;
newFrame.size.height = rect.size.height;
label.frame = newFrame;
[label sizeToFit];
UIView *whiteRoundedCornerView = (UIView *)[sctvCell.contentView viewWithTag:1000];
CGRect newFrame2 = whiteRoundedCornerView.frame;
newFrame2.size.width = 300;
newFrame2.size.height = rect.size.height + 160;
[ whiteRoundedCornerView setFrame:newFrame2];
}
if ((unsigned long)indexPath.row == [self.entries count] - 1){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
NewsFetchParseOperation *p = [[NewsFetchParseOperation alloc]init];
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
p.cat = appRecord.Category;
self.intindex = self.intindex + 1;
p.index = [NSString stringWithFormat:#"%d", (int)self.intindex];
p.lastid = appRecord.ids;
[p main];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self.tableView beginUpdates];
NSMutableArray *indexPaths = [NSMutableArray array];
NSInteger currentCount = self.entries.count;
for (NSUInteger i = 0; i < p.appRecordList.count; i++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:currentCount+i inSection:0]];
}
NSArray *temp_1 =[self.entries arrayByAddingObjectsFromArray:p.appRecordList];
self.entries = temp_1;
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView endUpdates];
});
});
}
return sctvCell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier = #"PlaceholderCell2";
SubcategoryTableViewCell * sctvCell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (sctvCell == nil) {
sctvCell= [[SubcategoryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
UILabel *label = (UILabel *)[sctvCell.contentView viewWithTag:1];
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"B MyFont" size:14.0f]};
CGRect rect = [appRecord.title boundingRectWithSize:CGSizeMake(label.frame.size.height - PADDING * 5, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
return rect.size.height + PADDING * 6;
}
and my cell subclass :
- (void)awakeFromNib {
self.news_img.layer.cornerRadius = 4;
self.news_img.clipsToBounds = YES;
self.resource_icon_img.layer.cornerRadius = 4;
self.resource_icon_img.clipsToBounds = YES;
self.contentView.backgroundColor = [UIColor clearColor];
self.whiteroundcorner = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,250)];
self.whiteroundcorner.backgroundColor = [UIColor whiteColor];
self.whiteroundcorner.layer.masksToBounds = NO;
self.whiteroundcorner.layer.cornerRadius = 3.0;
[self.whiteroundcorner.layer setShadowColor:[UIColor grayColor].CGColor];
self.whiteroundcorner.layer.shadowOffset = CGSizeMake(-1, 1);
self.whiteroundcorner.layer.shadowOpacity = 0.2;
self.whiteroundcorner.tag = 1000;
[self.contentView addSubview:self.whiteroundcorner];
[self.contentView sendSubviewToBack:self.whiteroundcorner];
}
im using story board for my table like this :
now problem is most of time the height calculated incorrectly.
also some time the height goes way beyond on cell and in the end of 10 cell
when i try to fetch new row the last cell apears incorrectly.
You will need to calculate the height for the cell after setting its content.
So something like this:
- (CGFloat)heightForCellAtIndexPath:(NSIndexPath *)indexPath {
static UITableViewCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
});
/* Method where you set the content of the cell */
[self configureCell: atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
[sizingCell setNeedsDisplay];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
I am trying to show a UIActivityIndicatorView while my table view is loading data and have it disappear once loading is finished. The loading indicator never appears. What am I doing wrong?
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define storeURL [NSURL URLWithString: #"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=PL9DC706DCCCE00188&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"]
#import "BBYoutubeVideosTableViewController.h"
#import "Reachability.h"
#import "TSMessage.h"
#import "TSMessageView.h"
#import "YoutubeCell.h"
#import "KFBYoutubeVideoView.h"
#import "KFBAppDelegate.h"
#interface BBYoutubeVideosTableViewController ()
{
UIActivityIndicatorView *loadingIndicator;
}
#end
#implementation BBYoutubeVideosTableViewController
#synthesize title, videoID, thumbURL, descriptionString, url, titleArray, videoIDArray, thumbArray, descriptionArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
UIImageView *backgroundImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"plain_app-background.png"]];
CGFloat width = [[UIScreen mainScreen]bounds].size.width;
CGFloat height = [[UIScreen mainScreen]bounds].size.height;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width / 2, height / 2, 37, 37)];
loadingIndicator.center = CGPointMake(width / 2, height / 2 - 37);
}
else
{
loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(142, 365, 37, 37)];
}
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
loadingIndicator.hidesWhenStopped = YES;
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if(networkStatus == NotReachable)
{
[TSMessage showNotificationWithTitle:#"Network Error" subtitle:#"No active network connection!" type:TSMessageNotificationTypeError];
[loadingIndicator stopAnimating];
}
else {
[self.tableView addSubview:loadingIndicator];
[loadingIndicator startAnimating];
}
self.title = #"Bluegrass & Backroads";
self.tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
self.tableView.backgroundView = backgroundImage;
url = [NSURL URLWithString:#"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=PL9DC706DCCCE00188&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
if (data == nil)
{
NSLog(#"data is nil");
}
else
{
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
}
});
}
- (void)viewDidDisappear:(BOOL)animated
{
[loadingIndicator stopAnimating];
}
- (void)fetchedData:(NSData *)responseData
{
NSError *error;
titleArray = [[NSMutableArray alloc]init];
videoIDArray = [[NSMutableArray alloc]init];
thumbArray = [[NSMutableArray alloc]init];
descriptionArray = [[NSMutableArray alloc]init];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray *items = [json objectForKey:#"items"];
for (NSDictionary *item in items)
{
NSDictionary *snippet = [item objectForKey:#"snippet"];
title = [snippet objectForKey:#"title"];
videoID = [[snippet objectForKey:#"resourceId"] objectForKey:#"videoId"];
thumbURL = [[[snippet objectForKey:#"thumbnails"] objectForKey:#"default"] objectForKey:#"url"];
descriptionString = [snippet objectForKey:#"description"];
[titleArray addObject:title];
[videoIDArray addObject:videoID];
UIImage *thumbnailImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]]];
[thumbArray addObject:thumbnailImage];
[descriptionArray addObject:descriptionString];
}
[self.tableView reloadData];
[loadingIndicator stopAnimating];
}
- (IBAction)morePressed:(id)sender
{
NSURL *kyfbVideos = [NSURL URLWithString:#"https://www.youtube.com/playlist?list=PL9DC706DCCCE00188"];
[[UIApplication sharedApplication] openURL:kyfbVideos];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [titleArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 215;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 60;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)];
footerView.backgroundColor = [UIColor clearColor];
CGFloat width = footerView.frame.size.width;
UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
moreButton.backgroundColor = [UIColor clearColor];
[moreButton setTitle:#"More" forState:UIControlStateNormal];
[moreButton setTitleColor:kfbBlue forState:UIControlStateNormal];
moreButton.titleLabel.textAlignment = NSTextAlignmentCenter;
moreButton.titleLabel.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:25.0];
moreButton.frame = CGRectMake(width / 2 - 25, 0, 50, 50);
moreButton.layer.cornerRadius = 25.0;
moreButton.layer.borderWidth = 2.0f;
moreButton.layer.borderColor = kfbBlue.CGColor;
moreButton.clipsToBounds = YES;
moreButton.backgroundColor = [UIColor clearColor];
[moreButton addTarget:self action:#selector(morePressed:) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:moreButton];
return footerView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
YoutubeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"youtubeCell"];
if (!cell)
{
NSArray *nibs =[[NSBundle mainBundle] loadNibNamed:#"YoutubeCell" owner:self options:NULL];
cell = [nibs firstObject];
}
cell.videoTitle.text = [titleArray objectAtIndex:indexPath.row];
cell.videoDescription.text = [descriptionArray objectAtIndex:indexPath.row];
cell.videoThumbnail.image = [thumbArray objectAtIndex:indexPath.row];
cell.videoTitle.textColor = kfbBlue;
cell.videoDescription.textColor = kfbBlue;
cell.videoTitle.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:22.0];
cell.videoDescription.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:16.0];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
KFBYoutubeVideoView *videoView = [[KFBYoutubeVideoView alloc]init];
videoView.videoIDString = [videoIDArray objectAtIndex:indexPath.row];
videoView.videoTitle = [titleArray objectAtIndex:indexPath.row];
videoView.videoDescription = [descriptionArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:videoView animated:YES];
}
else
{
KFBYoutubeVideoView *videoView = [[KFBYoutubeVideoView alloc]initWithNibName:nil bundle:nil];
videoView.videoIDString = [videoIDArray objectAtIndex:indexPath.row];
videoView.videoTitle = [titleArray objectAtIndex:indexPath.row];
videoView.videoDescription = [descriptionArray objectAtIndex:indexPath.row];
NSMutableArray *details = [self.splitViewController.viewControllers mutableCopy];
UINavigationController *detailNav = [[UINavigationController alloc]initWithRootViewController:videoView];
[details replaceObjectAtIndex:1 withObject:detailNav];
KFBAppDelegate *appDelegate = (KFBAppDelegate *)[[UIApplication sharedApplication]delegate];
appDelegate.splitViewController.viewControllers = details;
appDelegate.window.rootViewController = self.splitViewController;
appDelegate.splitViewController.delegate = videoView;
[appDelegate.splitViewController viewWillAppear:YES];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I figured it out. tableView was being initialized after adding loadingIndicator as a subview.