Trying to construct a tableview with a navigation bar at top - ios

Here's the code I used. What am I missing?
- (void)loadView
{
CGSize screen_size = [[UIScreen mainScreen] bounds].size;
CGFloat navBarHeight = 40;
UINavigationBar *nav = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, screen_size.width, navBarHeight)];
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, navBarHeight, screen_size.width, screen_size.height - navBarHeight) style:UITableViewStylePlain];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
table.delegate = self;
table.dataSource = self;
table.editing = YES;
[table reloadData];
[self.view addSubview:nav];
[self.view addSubview:table];
[nav release];
[table release];
}
Instead of a nav bar with a table underneath, I get a black screen under the status bar.

You need to create a containing view in your loadView method and set it as the view on your view controller:
- (void)loadView {
CGSize screen_size = [[UIScreen mainScreen] bounds].size;
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,screen_size.width,screen_size.height)];
self.view = myView;
CGFloat navBarHeight = 40;
UINavigationBar *nav = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, screen_size.width, navBarHeight)];
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, navBarHeight, screen_size.width, screen_size.height - navBarHeight) style:UITableViewStylePlain];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
table.delegate = self;
table.dataSource = self;
table.editing = YES;
[table reloadData];
[self.view addSubview:nav];
[self.view addSubview:table];
[nav release];
[table release];
[myView release];
}
Or alternately, if you have a nib file associated with your view controller then you should be using the viewDidLoad method instead of loadView.

Related

UICollectionView can't show all content

I init the collectionview with this(with code not the storyboard):
-(id) init{
self = [super init];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.page = 0;
self.step = 20;
self.subCateItems = [[NSMutableArray alloc] init];
self.scaleFactor = [[UIScreen mainScreen] bounds].size.width / 375.f;
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(9.f*self.scaleFactor, 6.f*self.scaleFactor, 0, 6.f*self.scaleFactor);
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
_collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
self.page = 0;
[self updateData];
}];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[_collectionView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_collectionView];
return self;
}
but the collection view seems can't show all the collection cells:
How to fix this?
as comments have suggested, I have caputured the view hierarchy of the views
Judging from your scroll view indicators, the bottom inset of the scroll view is set incorrectly, as it underlaps UITabBar. The code is in Swift but you should get the idea ;-)
I usually do this to make my scroll views appear on top:
_collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, -50, 0)
_collectionView.contentInset = UIEdgeInsetsMake(0, 0, -50, 0)
Also, make sure to make this:
self.automaticallyAdjustsScrollViewInsets = false
The first problem is here
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
Must be like this
self.view = [[UIView alloc] initWithFrame:self.view.bounds];
Then, who is the self ? Is it tab of UITabBarController?
If yes, all is good. If no then you will set correct inset ofUICollectionView

UITableView over scroll to bottom but top is normal

added in viewDidLoad
navgationBar.translucent =N0, iOS 10.3, xcode 8.3
- (void)__setUpUI{
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 64)];
[tableView registerNib:[UINib nibWithNibName:#"DXGroupMasterLikesCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([DXGroupMasterLikesCell class])];
_tableView = tableView;
_tableView.backgroundColor = [UIColor orangeColor];
tableView.delegate = self;
tableView.dataSource = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:tableView];}
like this
but if I set [self.view addSubview:[UIView new]]; before [self.view addSubview:tableView]; everything is ok
somebody know why ?

iOS8: Not show UIPopoverController but iOS7 is OK

Apple seems to change the attitude of UIPopoverController since iOS8.
Please look at the code below. I want to show UIPopoverController after addSubview. iOS6 and iOS7 are no problem but it does not display on iOS8.
Could you suggest any possible reasons? Any help will be appreciated it.
- (IBAction)tapButton:(id)sender {
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
[UIScreen mainScreen].bounds.size.height / 2,
200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
[self.view.window addSubview:sampleView];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
}
// On iOS7 is OK but not show on iOS8
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:sampleView.label
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
Update1:
I followed by this question's answer.
in iOS8: UIPopoverController presentPopoverFromRect not work for keyWindow any more
This is updated code.
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
As far as I checked, keyWindos and self.view.window seems to be same.
NSLog(#"%#", [UIApplication sharedApplication].keyWindow);
NSLog(#"%#", self.view.window);
However, this is not complete solution for my case. I want to control views on the added subview.
Update2:
I guess that I need to use UIPopoverPresentationController on iOS8.
- (IBAction)tapButton:(id)sender {
// View
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
// Label
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
// View Controller
UIViewController *viewController = [[UIViewController alloc] init];
viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.view = sampleView;
// UIPopoverPresentationController
UIPopoverPresentationController *presentationController = viewController.popoverPresentationController;
[presentationController setDelegate:self];
presentationController.permittedArrowDirections = 0;
presentationController.sourceView = [[UIApplication sharedApplication] keyWindow];
presentationController.sourceRect = [[UIApplication sharedApplication] keyWindow].bounds;
[viewController setPreferredContentSize:CGSizeMake(320, 480)];
[self presentViewController:viewController animated:YES completion:nil];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
vc.modalPresentationStyle = UIModalPresentationPopover;
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
self.popover.delegate = self;
}
[self.popover presentPopoverFromRect:CGRectMake(300, 300, 0, 0)
inView:viewController.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
Update3 I used dispatch_async but not worked. Some say that dispatch_async is effective in this case. dispatch_async is very simple solution. I prefer to use it. If you can fix my problem by using dispatch_async, I would be grateful you could attache the code.
- (IBAction)tapButton:(id)sender {
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
[UIScreen mainScreen].bounds.size.height / 2,
200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
[self.view.window addSubview:sampleView];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
}
// I tried this but not worked.
dispatch_async(dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:sampleView.label
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
}
Try and do the following for iOS 8
dispatch_async( dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0) inView:sampleView.label permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
EDIT
This is my code, it works With or without dispatch_async.
self.popover = [[UIPopoverController alloc] initWithContentViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"second"]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:self.button.frame inView:self.button permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});

Add existing view controllers in scrollview

I have two view controllers and I wanted to add this as subview of my scrollview, but, when I add these view controllers the second controller is only displayed.
This is my code.
- (void)viewDidLoad
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:scrollView];
[scrollView setBounces:NO];
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(320*2, 460);
controllers = [[NSMutableArray alloc] initWithCapacity:0];
First *first = [self.storyboard instantiateViewControllerWithIdentifier:#"First"];
[scrollView addSubview:first.view];
[controllers addObject:first];
Second *second = [self.storyboard instantiateViewControllerWithIdentifier:#"Second"];
[scrollView addSubview:second.view];
[controllers addObject:second];
}
Thanks in advance.
Just give you an example, you can adjust their frame according to your requirement.
- (void)viewDidLoad
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:scrollView];
[scrollView setBounces:NO];
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(320*2, 460);
controllers = [[NSMutableArray alloc] initWithCapacity:0];
First *first = [self.storyboard instantiateViewControllerWithIdentifier:#"First"];
[scrollView addSubview:first.view];
first.view.frame = CGRectMake(0.0, 0.0, 320.0, 460.0) ;
[controllers addObject:first];
Second *second = [self.storyboard instantiateViewControllerWithIdentifier:#"Second"];
[scrollView addSubview:second.view];
second.view.frame = CGRectMake(320.0, 0.0, 320.0, 460.0) ;
[controllers addObject:second];
}

UICollectionView with UICollectionFlowLayout not displaying cells in the right location

I have a UICollectionView in a test project that I created which does not use Interface Builder. When I run the app the test views that I give to the collection view, via the datasource, are displayed in the the top right corner around (0,0). And I cannot for the life of me figure out why. I have tried adding constraints to the cell's content view. I have also tried messing with the item insets delegate function, but that does not seem to make a difference. Am I missing something?
Here is the code for the test view controller.
#import "TestViewViewController.h"
#interface TestViewViewController () <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
#property (strong, nonatomic) UICollectionView *collectionView;
#property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout;
#property (strong, nonatomic) NSMutableArray *testViews;
#end
#implementation TestViewViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView {
self.view = [[UIView alloc] init];
self.view.backgroundColor = [UIColor whiteColor];
self.flowLayout = [[UICollectionViewFlowLayout alloc] init];
self.testViews = [[NSMutableArray alloc] init];
UIView *testView = [[UIView alloc] init];
testView.backgroundColor = [UIColor blueColor];
testView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *testLabel = [[UILabel alloc] init];
testLabel.translatesAutoresizingMaskIntoConstraints = NO;
testLabel.text = #"I hate collection views.";
[testView addSubview:testLabel];
testView = [[UIView alloc] init];
testView.backgroundColor = [UIColor redColor];
testView.translatesAutoresizingMaskIntoConstraints = NO;
testLabel = [[UILabel alloc] init];
testLabel.translatesAutoresizingMaskIntoConstraints = NO;
testLabel.text = #"I really do.";
[testView addSubview:testLabel];
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flowLayout];
self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.backgroundColor = [UIColor grayColor];
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"MyCell"];
NSDictionary *views = #{#"collectionView": self.collectionView};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[collectionView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[collectionView]|" options:0 metrics:nil views:views]];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return self.testViews.count;
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
NSLog(#"%i", self.testViews.count);
[cell.contentView addSubview: self.testViews[indexPath.row]];
return cell;
}
#pragma mark – UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// UIView *statView = self.testViews[indexPath.row];
return CGSizeMake(100.0, 100.0);
}
#end
For openers the CGRectZero macro is the equivalent of CGRectMake(0, 0, 0, 0). It would seem that you'd be in trouble with a definition of the space in which the collection view was to be drawn and the CGRectZero origin of 0,0 would put it in the upper left corner of the view. I tried creating an app with your code - and finally got something to show up when I got the code for loadView to look like this:
- (void) loadView
{
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view.backgroundColor = [UIColor whiteColor];
self.flowLayout = [[UICollectionViewFlowLayout alloc] init];
self.testViews = [[NSMutableArray alloc] init];
UIView* testView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 320, 80)];
testView.backgroundColor = [UIColor blueColor];
testView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel* testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 80)];
testLabel.translatesAutoresizingMaskIntoConstraints = NO;
testLabel.text = #"I hate collection views.";
[testView addSubview:testLabel];
[self.testViews addObject:testView];
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, 320, 320) collectionViewLayout:self.flowLayout];
self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.backgroundColor = [UIColor grayColor];
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"MyCell"];
}
The difference being that objects were created with a frame size - that views were added into views and so on.
My thought is that you'd be better off creating your UICollectionViewin a XIB - setting all the parameters there and also creating a subclass for UICollectionViewCell to be able to do more with the contents of the cells as need be. There's a whole lot more to be done to make this a usable UICollectionView with an arbitrary number of cells, but I have to say, the UICollectionView is not an easy object to deal with - so I sympathize with you as you come up the learning curve.

Resources