Display a label covering the whole UITableView - ios

I'd like to display a big fat label overlayed on top of my UITableView if there are no elements to be displayed. (This label would provide instructions on how to add elements.) I wonder what the best method would be to achieve this.
I tried dragging a UIView on my UITableView. I thought I could add labels there and then set the .hidden property programmatically. However, it seems to be tricky to embed the UIView in the UITableView using IB.
Is it possible to create the label programmatically and have it cover a big chunk of my UITableView (i.e., not just be in a particular cell of the table)?

There is no need to add a special overlay view for this purpose.
you can do this by assigning the created label to the property self.tableView.backgroundView in the numberOfSectionsInTableView method of the UITableViewDelegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (loans) { // check if the data is present or not
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
return 1;
} else { // if not present
// Display a message when the table is empty
UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
messageLabel.text = #"No data is currently available.";
messageLabel.textColor = [UIColor blackColor];
messageLabel.numberOfLines = 0;
messageLabel.textAlignment = NSTextAlignmentCenter;
messageLabel.font = [UIFont fontWithName:#"Palatino-Italic" size:20];//
[messageLabel sizeToFit];
self.tableView.backgroundView = messageLabel;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return 0;
}

If you don't want to do it yourself: https://github.com/dzenbot/DZNEmptyDataSet
Otherwise create a label programmatically and add it like this:
let myLabel = UILabel(frame: myTableView.frame)
myLabel.text = "Hello World"
self.view.addSubview(myLabel)
myTableView.hidden = true

If you want to just provide insructions and then want to remove overlayed view or any.
Create View
var DynamicView=UIView(frame: self.view.frame) DynamicView.alpha = 0.5
self.view.addSubview(DynamicView)
Add Label to DynamicView at position where you want....
Add tapGesture to dismiss/hide view.
var tapGesture = UITapGestureRecognizer(target: self, action:
"tapDetected") self.
DynamicView.alpha.addGestureRecognizer(tapGesture)
create "tapDetected" method and write code to hide DynamicView

Related

Changing NavigationItem Title in viewDidAppear in iOS

I've set the NavigationItem.title in Interface builder for readability but in code i need to do
self.navigationItem.title = SomeThingThatComesFromDB
I've Tried to do this in viewDidLoad and viewDidAppear but in first app launching the title is still the thing that I've set in interface builder.
How I can fix this?
This is my root view controller for application launch and here is the code that I'm using:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
for (Branch *b in [UserManager sharedInstance].branches) {
if ([b.branchId isEqualToString: [UserManager sharedInstance].vendorId]) {
self.title = b.branchName;
}
}
}
You got the following comparison in place to set/update the navigation item's title.
if ([b.branchId isEqualToString: [UserManager sharedInstance].vendorId]) {
self.title = b.branchName;
}
Problem seems to be that the [UserManager sharedInstance].vendorId] variable is not set (yet), when you call the function to update a navigation item's title. As you are able to set it correctly, after the view had disappeared and appeared back again.
The below code illustrates once again how one can set a navigation item's title, as you also did:
If you want to update the title in general for all related navigation elements (UITabbarController tabs, UINavigationController back button etc.) simply use:
self.navigationItem.title = SomeThingThatComesFromDB
https://developer.apple.com/reference/uikit/uiviewcontroller/1621364-title
If you got a dedicated navigation item in your UINavigationController's bar, you could access it the following way (make sure, there is only one to access)
self.navigationItem.rightBarButtonItem.title = SomeThingThatComesFromDB
self.navigationItem.leftBarButtonItem.title = SomeThingThatComesFromDB
Try out below code:
CGRect rect = self.navigationController.navigationBar.frame;
UIView *myView = [[UIView alloc] init];
UILabel *title = [[UILabel alloc] init];
[title setFont:[UIFont systemFontOfSize:18.0]];
title.text = *SomeThingThatComesFromDB*;
title.textColor = [UIColor whiteColor];
CGSize size = [title.text sizeWithAttributes:
#{NSFontAttributeName:
title.font}];
title.frame = CGRectMake(20, 0, size.width, rect.size.height);//40
myView.frame = CGRectMake(0, 0, 40+size.width, rect.size.height);
[myView addSubview:title];
self.navigationItem.titleView = myView;

Can I put a UIScrollView inside another UIScrollView

I have a UIScrollView which scrolls only in vertical direction, I need to place UIScrollView which can move horizontally, like the AppStore application in apple devices. I don't want to us UICollectionView since I have static data and I have to only 3 horizontal UIScrollView
Yes you can. As UIScrollView subclasses UIView it will behave as expected when adding subviews. Each scroll view will enable scrolling based on its contentSize property.
Objective-C:
UIScrollView *horizontalScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(40.0, 40.0, 300.0, 300.0)];
horizontalScrollView.backgroundColor = [UIColor lightGrayColor];
horizontalScrollView.contentSize = CGSizeMake(2000.0, 300.0);
[self.view addSubview:horizontalScrollView];
UIScrollView *verticalScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(40.0, 40.0, 220.0, 220.0)];
verticalScrollView.backgroundColor = [UIColor greenColor];
verticalScrollView.contentSize = CGSizeMake(220.0, 2000.0);
[horizontalScrollView addSubview:verticalScrollView];
Swift:
let horizontalScrollView = UIScrollView(frame: CGRectMake(40.0, 40.0, 300.0, 300.0))
horizontalScrollView.backgroundColor = UIColor.lightGrayColor()
horizontalScrollView.contentSize = CGSizeMake(2000.0, 300.0)
self.view.addSubview(horizontalScrollView)
let verticalScrollView = UIScrollView(frame: CGRectMake(40.0, 40.0, 220.0, 220.0))
verticalScrollView.backgroundColor = UIColor.greenColor()
verticalScrollView.contentSize = CGSizeMake(220.0, 2000.0)
horizontalScrollView.addSubview(verticalScrollView)
Yes you can. But you need to differentiate the scroll views in scroll view delegate methods. Either you can use tags or if you are declaring them as global variables in the entire class,you can directly access them with their names.Eg:
UIScrollView *parentScrollView = [[UIScrollView alloc] init];
parentScrollView.delegate = self;
[self.view addSubview:parentScrollView];
UIScrollView *childScrollView = [[UIScrollView alloc] init];
childScrollView.delegate = self;
[parentScrollView addSubview:childScrollView];
Now inside delegate method you can check for the scroll view like
if(scrollview == parentScrollview)
{
// do your actions
}
This is possible only if your scroll view objects are global to the class. You can also give a tag and check for the tag in scroll view delegate method like
parentScrollView. tag = 101;
And in scroll view delegate method
if(scrollview.tag = 101)
{
// do your actions
}
yes it is possible but you have to maintain tag of scrollview for handling delegate methods of scroll view.
UIScrollView has a property called scrollEnabled, which you can set to NO to disable scrolling in your parent scroll view.
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if(scrollView == innerView)
outerView.scrollEnabled = NO;
else
outerView.scrollEnabled = YES;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if(scrollView == innerView)
{
if(innerView.contentOffset.x + innerView.frame.size.width == innerView.contentSize.width)
{
outerView.scrollEnabled = NO;
}
else
{
outerView.scrollEnabled = YES;
}
}
}
Or else you can go through the below link.

How to show only the checkmark selection without the selection of entire UITableViewCell in edit mode of UITableView?

I have a TableView with custom UITableViewCells. I have UILongPressGestureRecognizer enabled for my tableview cells. On long tap of gesture recognizers, I wanted to edit my tableview. Now in the edit mode of the tableview, all the cells that are selected are getting selected along with the accessory checkmark button. I want only the accessory checkmark button to be selected and not the entire cell. I tried multiple options like setting the selectionStyle property of the cell as UITableViewCellSelectionStyleNone . In this case i am not able to select the cells in edit mode.
-(void)addLongPressGestureRecognizerForCell:(UITableViewCell *)tableViewCell{
UILongPressGestureRecognizer *lLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGestureFunction:)];
lLongPressGesture.minimumPressDuration = 0.3;
lLongPressGesture.delegate = self;
[tableViewCell addGestureRecognizer:lLongPressGesture];
[lLongPressGesture setCancelsTouchesInView:NO];
}
How to achieve this functionality?
A simpler solution—and one that doesn't require changing the background to gray—is to set the multipleSelectionBackgroundView of your UITableViewCell to a clear box.
In Swift:
override func awakeFromNib()
{
super.awakeFromNib()
// Hide selection box in multi-select mode.
multipleSelectionBackgroundView = UIView()
multipleSelectionBackgroundView?.backgroundColor = UIColor.clearColor()
}
In Objective-C:
- (void)awakeFromNib
{
[super awakeFromNib];
// Hide selection box in multi-select mode.
self.multipleSelectionBackgroundView = [[UIView alloc] init];
self.multipleSelectionBackgroundView.backgroundColor = [UIColor clearColor];
}
Finally Got the Answer!!!!
All I need was to override the setSelected method and change the selectedBackgroundView for my tableViewCell in my custom tableViewCell class.
First i have added the backgroundview for my tableViewCell in cellForRowAtIndexPath method.
lCell.selectedBackgroundView = [[UIView alloc] init];
Next i have overridden the setSelected method as mentioned below.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
UIImageView *lBalloonView = [self viewWithTag:102];
[lBalloonView setBackgroundColor:[[UIColor hs_globalTint] colorWithAlphaComponent:0.2]];
UITextView *lMessageTextView = [self viewWithTag:103];
lMessageTextView.backgroundColor = [UIColor clearColor];
UILabel *lTimeLabel = [self viewWithTag:104];
lTimeLabel.backgroundColor = [UIColor clearColor];
}
Also one of the most important point to be noted is to change the tableViewCell selection style.
lTableViewCell.selectionStyle = UITableViewCellSelectionStyleGray;

Custom UITableViewCell didSelectRowAtIndexPath not being called

I have created a custom UITableViewCell class that I use to draw my UITableViewCell. Everything is drawn correctly however due to the elements I am putting into my UITableViewCell I have been having problems with selecting the cell.
This is the method I use to draw the UITableViewCell which is my custom UITableViewCell
- (void)drawCell
{
nameString = [[UILabel alloc] init];
nameString.backgroundColor = [UIColor redColor];
nameString.frame = CGRectMake(15.0, 0.5, 70.0, 40.0);
nameString.text = [itemsDictionary objectForKey:#"Name"];
lastNameString = [[UILabel alloc] init];
lastNameString.backgroundColor = [UIColor clearColor];
lastNameString.frame = CGRectMake(105.0, 0.5, 95.0, 40.0);
lastNameString.text = [itemsDictionary objectForKey:#"LastName"];
addressString = [[UILabel alloc] init];
addressString.backgroundColor = [UIColor clearColor];
addressString.frame = CGRectMake(220.0, 10.5, addressString.frame.size.width, 50.0);
addressString.text = [NSString stringWithFormat:#"ISN %#: %#",[itemsDictionary objectForKey:#"AddNumber"] ,[itemsDictionary objectForKey:#"AddString"]];
[addressString sizeToFit];
// scrollcell has a dynamic scrollwidth depending on the sddressString but has a framesize of a normal UITableViewCell
scrollCell = [[UIScrollView alloc] init];
scrollCell.backgroundColor = [UIColor blueColor];
scrollCell.frame = CGRectMake(0.0, 0.0, ScreenWidth, 45.0);
[scrollCell setContentSize:(CGSizeMake((220.0 + addressString.frame.size.width)+15, 45.0))];
[scrollCell addSubview:nameString];
[scrollCell addSubview:lastNameString];
[scrollCell addSubview:addressString];
[[self contentView] addSubview:scrollCell];
}
As you can see I am adding a UIScrollView that covers the entire cell which I think is preventing the UITableViewCell delegate selection method.
How can I get the delegate method didSelectRowAtIndexPath to work?
Have you added the following?
#implementation ViewController <UITableViewDelegate, UITableViewDataSource>
and set the delegate to self?
self.tableview.delegate = self;
A UIScrollView in a cell is always going to be a problem because it intercepts events. If you can, rely on the fact that the table view scrolls and make the cell as large as it needs to be to display the content.
If you must have the scroll view there you will probably have to add a view over the top of the cell, add your own gesture recognisers, and choose which events will be sent to the table view and which to the scrollview.
Check out this answer also - you can send touchesBegan/Moved/Ended to nextResponder also.
One of the other two answers is probably the right path but just in case if you are using storyboard segue those will get before didSelectRowAtIndexPath so code you have in there may be irrelevant depending on the segue and what happens.

Calling a UITableViewDelegate method from ViewController

I'd like to call the following method from my view controller class:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
However for the life of me I can't figure out how to do it. I tried:
UIView *view = [tableView viewForHeaderInSection:section];
UIView *view = [self viewForHeaderInSection:section];
UIView *view = [self tableView:viewForHeaderInSection:section];
All give me errors. It's that extra tableView: bit on the beginning. Can anyone give some advice or at least explain what that tableView:(UITableView *)tableView means?
Thanks!
Steve
I don't know why you would want to call it, but if it is implemented in the same object that you're calling it from then you can use self:
UIView* view = [self tableView:tableView viewForHeaderInSection:section];
otherwise, you can get the delegate from the tableView and call the delegate:
id<UITableViewDelegate> theDelegate = tableView.delegate;
UIView* view = [theDelegate tableView:tableView viewForHeaderInSection:section];
Why would you want to call it? This is one of the UITableViewDelegate methods that are normally called automatically when the table is being constructed by the tableView. The tableView class object fills in the parameters that it needs when it makes the call to this method. The view controller only needs to provide the right delegate methods, customized by you, so it can set it up properly.
Did you customize the code, as in this example, in your delegate class?
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// create the parent view that will hold header Label
UIView* customView = [[UIView alloc] initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)];
// create the button object
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor blackColor];
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont boldSystemFontOfSize:20];
headerLabel.frame = CGRectMake(10.0, 0.0, 300.0, 44.0);
// If you want to align the header text as centered
// headerLabel.frame = CGRectMake(150.0, 0.0, 300.0, 44.0);
headerLabel.text = <Put here whatever you want to display> // i.e. array element
[customView addSubview:headerLabel];
return customView;
}
I'm not near my Mac, or I would give you one of my own examples. But this is the general way this method is used.
By the way, you can see that the parameter tableView is not referenced in the sample code above. If you really want to call this method, use nil. UITableViewDelegate protocol allows the controller to be delegate for more than one tableView. If this happens, the method should test to see which tableView is reference, so that specialized behavior can be accommodated for each tableView.
Additional info:
If you just want to see what the height of your tableView's header is, you can evaluate its sectionHeaderHeight property. There are other properties like this, such as sectionFooterHeight and rowHeight.
You should know that delegate methods are there to help the tableView, using your customization. So the delegate method tableView:heightForHeaderInSection: is actually for you to customize the header height. Your delegate methods tells the tableView what the height is. It isn't a way to examine a property of the tableView.
Apples documentation says that if you customize by using tableView:heightForHeaderInSection: then the tableView sectionHeaderHeight is not valid. You would expect this, because that property refers to the height of all of the section headers.
Using the sectionHeaderHeight property, which you can write to in this case, you can set all of the headers to the same height.
Here is some sample code from something I'm working on now. I've added an NSLog statement for you.
resultsTableVC = [[[ResultsTableVC alloc] initWithController:self] retain];
self.tableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 110, self.view.frame.size.width, self.view.frame.size.height-120) style:UITableViewStyleGrouped] retain];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.tableView.autoresizesSubviews = YES;
self.tableView.layer.cornerRadius = 10.0f;
self.tableView.delegate = resultsTableVC;
self.tableView.dataSource = resultsTableVC;
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.separatorColor = [UIColor defaultResultTableBackgroundColor];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
[self.view addSubview:self.tableView];
NSLog(#"header: %f, row: %f", tableView.sectionHeaderHeight, tableView.rowHeight);
(Someone will probably point out that I don't need some of those retains. I'm still working on that.)
This tells me that the standard section height is 100 and the standard row height is 44.0. I have a pointer to my tableView, a property that I can use through this class.
Now if you are setting the header height using tableView:heightForHeaderInSection: then you should have the height already calculated in your program. I don't think you can query for the height of a particular section (or row) once you set it.
Does this help?

Resources