Xcode: How to fix the toolbar for a tableView? - xcode

I have a tableView and want to add a toolbar at the bottom with a sync button and the latest sync date (like on the Mail-app on the iPhone). But the Scrollbar should be fixed, so that it doesn't move when I scroll trough the table view.
Right now, I'm just adding the searchBar programmatically by:
self.tableView.tableFooterView = self.toolbar;
Another problem linked here is the fact, that I'm using the MasterDetailsView Controller template of Xcode. But I can't just drag a toolbar into my MasterView (containing the tableview). My first guess is that its just fixed because of the template I used but I'm not quite sure about it.
Thanks in advance!!

Instead of using a UITableViewController try using a plain UIViewController which conforms to UITableViewDelegate and UITableViewDataSource. Add a UITableView as a subview to the view controller's main view and link its delegate and datasource to the view controller.
Now, you can add any other UIViews to the main view which will appear fixed on top of the UITableView.

In your Story board for that ViewController, drag Bar Button Item to the Bottom after the tableView and in viewDidLoad method.. do the following..
self.navigationController.toolbarHidden = NO;

I think I found a really good solution to this.
In the storyboard view, drop the toolbar out of the Tableview. In the story board view this will leave it 'floating' above the view and the tool bar will no longer appear in your compiled code.
Too fix this, add the following to your view controller code
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let v = UIView()
let toolBarView : UIView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
mainToolBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)
toolBarView.addSubview(mainToolBar)
v.addSubview(toolBarView)
return v
}

Related

Put a View in bottom of Screen

I try to put a View to the bottom of the screen on my UiTableView. How can I do that? Now it is still the last row. I searched for it but I didnt found someting useful. I hope you guys can help me
Please put UIView below the UITableViewCell like this.
Drag the desired view to the bottom of the UITableView's contents, i.e. below all of the table's cells.
You can add this line inside your code for your table view cell bottom
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 60))
footerView.backgroundColor = UIColor.whiteColor()
return footerView
}

Why my UITextView text is not show from starting and hide under Navigation Bar

I wonder why my textview text didn't show up from starting text.
This is the image from my Xcode IB
When I run it on my iPhone 6 Simulator and others
Actually it should start from "Example Notification...."
Please help me out.
Those who didn't start UITextView from start,here is the answer.I am sure it worked 100% on iOS 8 and higher on any devices.
1.You need to deselect these at your view controller where textview is applied
Go to ViewController > Attribute Inspector > Search Extend Edges > Under Top Bars & Under Button Bars
2.Add the following code at your view controller
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.yourTextView.setContentOffset(CGPoint.zero, animated: false)
}
Special Thanks to #El Captain
To maintain UINavigationBar translucent and allow user to rotate the device while reading UITextView I used something like this:
private var firstLayout = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if firstLayout {
firstLayout = false
textView.setContentOffset(
CGPoint(x: 0, y: -topLayoutGuide.length), animated: false)
}
}
Tested on iOS 9 and iOS 12 Beta.
In my case it was iOS 13. UITextView was constrained to edges. It's content was set on did load, after that text view automatically scrolled to the bottom causing large title to shrink.
What helped me is to wrap setText in to async:
DispatchQueue.main.async {
textView.text = logs
}
You can also keep UINavigationBar isTranslucent and UIScrollViewContentInsetAdjustmentAutomatic,
Just to fix the textView is hidden by navigationBar, then add the below code:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[textView setContentOffset:CGPointMake(0, -self.view.layoutMargins.top) animated:NO];
}

UiScrollview with nested image looks weird

I have a UIScrollView inside a UIViewController (subclassed by ImageViewController). The ViewController itself is part of a NavigationController's stack. Now, apart from having a navigation bar, I want the ScrollView to take all of the available room on the screen. The UIImageView inside the scrollview should then fill the available room of the scroll view. You can see the current state at the bottom of this posting.
class ImageViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
var imageView: UIImageView?
var image: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
if let image = image {
imageView = UIImageView(image: image)
if let imageView = imageView {
imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: image.size)
scrollView.addSubview(imageView)
scrollView.contentSize = image.size
let scaleHeight = scrollView.frame.size.height / scrollView.contentSize.height
let scaleWidth = scrollView.frame.size.width / scrollView.contentSize.width
let minimumScale:CGFloat = min(scaleHeight, scaleWidth)
let maximumScale:CGFloat = max(scaleHeight, scaleWidth)
scrollView.minimumZoomScale = minimumScale
scrollView.maximumZoomScale = maximumScale
scrollView.zoomScale = maximumScale
}
}
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
}
The code leaves me with unnecessary borders (left, right, top). How do I get rid of them?
EDIT: With #Bxtr's suggestion and another stackoverflow thread I was able to remove the borders left and right to the scroll view. After some more digging I found out that by deactivating Adjust Scroll View Insets, the image inside the scroll view can be correctly vertically positioned. Still, I do not get the reason for the vertical misplacement in the first place...
Have you checked the margin/padding values, because it kinda looks so (same size on left and right border). If it is not the case, could you please also post your xml file of the activity so we can have every part of the puzzle to help you ?
scrollView.contentSize = image.size;
you have to tweek this line. You are explicitly setting scroll view content size to the image size. You have to set content size to fit the Width of Screen.
You can use a UIView in UIScrollView, and that UIView contains UIImage.
You need to set constraints properly.
After some more digging I found out that by deactivating Adjust Scroll
View Insets, the image inside the scroll view can be correctly
vertically positioned. Still, I do not get the reason for the vertical
misplacement in the first place...
The reason is that the view controller's automaticallyAdjustsScrollViewInsets property is by default YES, the following is from apple documentation:
automaticallyAdjustsScrollViewInsets
A Boolean value that indicates
whether the view controller should automatically adjust its scroll
view insets.
Default value is YES, which allows the view controller to adjust its
scroll view insets in response to the screen areas consumed by the
status bar, navigation bar, and toolbar or tab bar. Set to NO if you
want to manage scroll view inset adjustments yourself, such as when
there is more than one scroll view in the view hierarchy.
Besides setting automaticallyAdjustsScrollViewInsets = No, you can pin the scrollView to the topLayoutGuide (instead of to the top of the viewController's view) when using autoLayout.

Swift uiview on top of uitable

I have a simple to do list using a uitable inside a top bar and I want to create a overlay menu activated from one of the buttons on the top bar.
How can I set that menu uiview on top overlay of the uitable custom cell?
I am using Swift in the latest Xcode for ios8.
I am using the story board to try to insert the uiview or a ui container to set my menu. The idea is to initialise this view hidden and then a button on the top bar to show it. And this menu should have some uibuttons that I then want to create segways to different views. But I can't seem to be able to drag the view on top of the uitable in the storyboard. Is there a way? Even if using code?
Thanks.
You could programaticaly create a UIView:
var view2 = UIView(frame: CGRect(x: xPos, y: yPos, width: WIDTH, height: HEIGHT))
if you wan't to add buttons to the view you can do that:
var button = UIButton(frame: CGRect(x: xPos, y: yPos, width: WIDTH, height: HEIGHT))
button.titleLabel?.text = "ButtonTitle"
button.addTarget(self, action: Selector("functionToCallWhenClicked"), forControlEvents: UIControlEvents.TouchUpInside) //To do something when the button is tapped
self.view2.addSubview(button)//To add the button the the view2
And then you add view2 to the screen:
self.view.addSubview(view2)
If you wan't to remove the view2 from the screen:
self.view2.removeFromSuperview()
==> here Given Code Try iy
===>declare awView
awView = [AdWhirlView requestAdWhirlViewWithDelegate:self];
awView.center = CGPointMake(self.view.frame.size.width/2,
self.view.frame.size.height-kAdWhirlViewHeight/2);
[self.view addSubview:awView];
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGRect newFrame = awView.frame;
newFrame.origin.x = 0;
newFrame.origin.y = self.tableView.contentOffset.y+(self.tableView.frame.size.height-kAdWhirlViewHeight);
awView.frame = newFrame;
}

How to use dismiss an iPhone popover in an Adaptive Storyboard

I am new to iOS development, and am trying to learn storyboarding, Swift, and the new features of iOS 8 at the same time.
I have created a very simple storyboard that uses a Popover presentation segue to display another view. On the simulator, if I run this for an iPad, it works as expected. However, if I run it for an iPhone, instead of a popover, it displays a full-screen view, on top of the original view. This is fine; however, there is no way to dismiss it and go back to the original screen.
I have watched the WWDC 2014 video "228 A Look inside presentation controllers" and they can show a dismiss button if they build the user interface entirely with code.
I have also watched the "411 What's new in interface builder" session, where they say that this can be done in Interface Builder, but they do not show it, promising to show how to do it in the lab, if anyone is interested. Unfortunately, I did not attend WWDC 2014, or know anyone who has. My Google searches have not returned anything helpful either.
You could add the navigation controller like this-
Set your popover view controller as the root view controller to a navigation controller.
Delete the popover segue that you are currently using
Reconnect the segue from the button you are displaying the popover from to the navigation controller.
On iPad you will get a popover and on iPhone you will get a modal presentation. Both the iPad and iPhone will show the navigation controller. Depending on your use case this may or may not be something you want. Here's a screen show of what the storyboard should look like.
If you really do want your view controller to always be a popover leave your storyboard the way it is and add something like this to your view controller that presents the popover-
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Your segue name"]) {
UIViewController *yourViewController = segue.destinationViewController;
yourViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController;
popoverPresentationController.delegate = self;
}
}
The view controller presenting the popover will also need to respond to this UIPopoverPresentationDelegate method
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;//always popover.
}
Lastly, you could do the following to only add the navigation controller to the modal presentation of your view controller on the iPhone and leave the popover on iPad without a navigation controller.
Leave your storyboard as is.
The proper place to inject the navigation controller is in - (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style. In order for this to be called we must set ourselves as the delegate of the UIPopoverPresentationController.
Once again we will do this in prepareForSegue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Your segue name"]) {
UIViewController *yourViewController = segue.destinationViewController;
yourViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController;
popoverPresentationController.delegate = self;
}
}
Then we will do this in the delegate method that I mentioned above
-(UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
{
UIViewController *presentedViewController = controller.presentedViewController;
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:presentedViewController];
UIBarButtonItem *dismissButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone target:self action:#selector(done:)];
presentedViewController.navigationItem.rightBarButtonItem = dismissButton;
return navigationController;
}
Good Luck!
If what you want is a popover on your iPad but a modal sheet with a close button on your iPhone then you can do it without creating an extra navigation controller in storyboard for the popover.
In Xcode 6.3 storyboard, you simply hook up a view controller and designate the segue as a "Present as Popover"
The code below should go in the view controller that segues to the popover, not in the popover itself:
First you set up the popover delegate:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "myPopoverSegueName") {
let vc = segue.destinationViewController
vc.popoverPresentationController?.delegate = self
return
}
}
Then you add the delegate extension (below your view controller's code) and create the navigation controller / close button on the fly:
extension myViewController: UIPopoverPresentationControllerDelegate {
func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
let btnDone = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "dismiss")
let nav = UINavigationController(rootViewController: controller.presentedViewController)
nav.topViewController.navigationItem.leftBarButtonItem = btnDone
return nav
}
}
Then you add your dismiss function and you should be good to go:
func dismiss() {
self.dismissViewControllerAnimated(true, completion: nil)
}
I am not sure why you need to do storyboard setup for the Done button, all the work can be done programmatically with few lines of code. The important part is to implement some UIAdaptivePresentationControllerDelegate protocol methods exactly like below:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
return .FullScreen
}
func presentationController(controller: UIPresentationController,
viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController?{
var navController:UINavigationController = UINavigationController(rootViewController: controller.presentedViewController)
controller.presentedViewController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action:"done")
return navController
}
Then, a simple method to implement the dismissing behavior for the popover in case it was presented in full screen:
func done (){
presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
and you done!
In my case, I had a small popup that I wanted to be a popup on both an iPhone and iPad - and wanted to avoid using a navigation bar with a Dismiss. Discovered that one needed to implement two delegate calls (Swift 3.0):
extension MyViewController : UIPopoverPresentationControllerDelegate {
// Needed for iPhone popup
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
// Needed for iPhone in landscape
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return .none
}
}
Its possible to do it with mimimal code whilst putting the logic into the storyboard instead. In the view controller that presents the popover, just put in the marker method
#IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {
}
It does not need any code but needs to be present so you can control drag to the Exit icon later on when you use interface builder.
I have my popover content not take up the entire background view but have a small margin around it. This means you can use interface builder to create a tap gesture recogniser for this view. Control drag the gesture recogniser to the Exit icon which then pops up some Exit choices, one of which is the unwindToContainerVC method as seen above.
Now any tap around the edge (such as in an iPhone 4S scenario) takes you back to the presenting view controller.
Here is the connections inspector for the gesture recogniser:

Resources