Helping with swift layout (Simple for you not me lol) - swift

Hi I am learning how to make newsfeeds and although things are going well I would like some help in terms of the layout of the feed itself. The feed clips to the safe areas of the simulator but I want to move the top section down about half way down the screen. I have made the table view using a XIB and created the table view programatically. How would one be able to shift the top section down? Here is the code:
HomeViewScene = UITableView(frame: view.bounds, style: .plain)
HomeViewScene.backgroundColor = Colors.white
view.addsubview(tableview)
let cellNib = UINib(nibName: "PosterCell", bundle: nil)
HomeViewScene.register(cellNib, forCellReuseIdentifier: "postCell")
var layoutguide:UILayoutGuide
layoutguide = view.safeAreaLayoutGuide
HomeViewScene.leadingAnchor.constraint(equalTo: layoutguide.leadingAnchor).isActive = true
HomeViewScene.topAnchor.constraint(equalTo: layoutguide.topAnchor).isActive = true
HomeViewScene.trailingAnchor.constraint(equalTo: layoutguide.trailingAnchor).isActive = true
HomeViewScene.bottomAnchor.constraint(equalTo: layoutguide.bottomAnchor).isActive = true

It looks to me like you're pretty close. The 2 main things I would suggest are:
1) You need to set translatesAutoresizingMaskIntoConstraints to false if you want your constraints to actually take effect.
2) If you want your table view under your other view, you need to set your table view's top anchor to be equal to your other view's bottom anchor.
Specifically, this is how I would change the code you posted to solve your problem:
HomeViewScene = UITableView(frame: view.bounds, style: .plain)
HomeViewScene.backgroundColor = Colors.white
view.addsubview(tableview)
let cellNib = UINib(nibName: "PosterCell", bundle: nil)
HomeViewScene.register(cellNib, forCellReuseIdentifier: "postCell")
var layoutguide:UILayoutGuide
layoutguide = view.safeAreaLayoutGuide
HomeViewScene.translatesAutoresizingMaskIntoConstraints = false //Add this line
HomeViewScene.leadingAnchor.constraint(equalTo: layoutguide.leadingAnchor).isActive = true
HomeViewScene.topAnchor.constraint(equalTo: otherView.topAnchor).isActive = true //You need to make sure the TOP of the table view is positioned right at the BOTTOM of the other view
HomeViewScene.trailingAnchor.constraint(equalTo: layoutguide.trailingAnchor).isActive = true
HomeViewScene.bottomAnchor.constraint(equalTo: layoutguide.bottomAnchor).isActive = true
Remember that if you change constraints on a view programmatically, you must set translatesAutoresizingMaskIntoConstraints to false otherwise you will see no change to that view's position.

Related

How to achieve the auto-shrink SwiftUI Navigation Title with UIKit?

I am trying to achieve the auto-shrink large nav title like the Navigation Title in SwiftUI, but no matter what my nav title always stay shrinked and never appear in large title mode. How do i fix this? (code below)
func setup() {
table.translatesAutoresizingMaskIntoConstraints = false
table.dataSource = self
table.delegate = self
table.register(UITableViewCell.self, forCellReuseIdentifier: "mycell")
table.separatorColor = .white
table.backgroundColor = .black
let appearance = UINavigationBarAppearance()
appearance.titleTextAttributes = [.foregroundColor: UIColor.black]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
appearance.configureWithOpaqueBackground()
navigationItem.title = "Todo List"
navigationItem.scrollEdgeAppearance = appearance
navigationItem.standardAppearance = appearance
view.addSubview(table)
}
As well as providing a configuration for large titles, you need to instruct your navigationController to use large titles
navigationController.navigationBar.prefersLargeTitles = true
The default configuration for a view controller should be to automatically use large titles if that is the preferred choice. However you can set it explicitly per view controller:
navigationItem.largeTitleDisplayMode = .always // or .automatic or .never
If the nav controller has prefersLargeTitle = false then large titles will never be displayed whatever the largeTitleDisplayMode setting.

Why is the search bar pushing the navigation bar out of the picture?

I added a UISearchBar programmatically to my view and every time you activate the searchBar the navigation bar is pushed out of the picture.
My view's hierarchy
searchController.searchBar.delegate = self
navigationItem.title = navigationItem.title ?? ci("plan_p")
tableView.rowHeight = 100.0
tableView.tableHeaderView = searchController.searchBar
tableView.setContentOffset(CGPoint(x: 0.0, y: (self.tableView.tableHeaderView?.frame.size.height)!), animated: false)
guard let projectId = GlobalState.selectedProjectId, let byProject : Results<Structure> = self.by(projectId: projectId) else { return }
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Suche nach Plan"
definesPresentationContext = true
Probably your UITableView is top of the view hierarchy (or more components in top of the view hierarchy).
If your tableView in top of the view hierarchy you should change the tableView's hierarchy in your Interface Builder for solve this issue.
You can simply put your tableView in another UIView component for solve this issue.

Adding searchBar to tableHeaderView adds bottom empty space

I need to add UISearchController to UIViewController I know that the best way to do it is adding it to UINavigationController like this:
let resultSearchController = UISearchController(searchResultsController: athkarSearchTable)
resultSearchController?.searchResultsUpdater = athkarSearchTable
navigationItem.searchController = resultSearchController
The problem is I can't use UINavigationController so I found another solution: adding it to tableHeaderView like the following:
let resultSearchController = ({
let controller = UISearchController(searchResultsController: athkarSearchTable)
controller.searchResultsUpdater = athkarSearchTable
// to give a semi-transparent background when the search bar is selected.
controller.dimsBackgroundDuringPresentation = true
controller.searchBar.sizeToFit()
controller.searchBar.barStyle = UIBarStyle.default
controller.searchBar.searchBarStyle = .minimal
tableView.tableHeaderView = controller.searchBar
return controller
})()
// to limit the overlap area to just the View Controller’s frame instead of the whole Navigation Controller
definesPresentationContext = true
However, this solution adds an empty space to the bottom of the tableView in the UIViewController not the athkarSearchTable which is not good :/ as the screenshot below:
I tried to set the footer to an empty view and to set the height of footer to zero, none of them worked :/
Any suggestion how to remove the bottom empty space?
Problem solved by adding the following lines:
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 400

Can't get rid of a UIviewcontroller header

I am trying to get rid of a header(extra-padding) that appears on the top of my view when I run the simulator. I have tried by setting the layout reference size to zero but is not working. The collectionview is only a small part of my screen that is why I'm not sure what it is. The header looks like that of a navigationview.
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.headerReferenceSize = CGSize.zero
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
cv.dataSource = self
cv.delegate = self
cv.isPagingEnabled = true
cv.showsHorizontalScrollIndicator = false
return cv
}()
With translucent navigation view controller's view content starts from top of navigation bar. If you want to layout view to start from bottom of navigation bar, set isTranslucent to false (available in interface builder).
Use proper contentInset of collection view
thanks for the help! I finally realized what it was, I'm doing my views programmatically and didn't realize that my view was a navigationController.
Here's what did it for me:
self.navigationController?.isNavigationBarHidden = true;

TVOS : Adjust the position of searchbar in UISearchViewController

I am developing an TVOS app. I use below code to implement search feature in UITabBarController. The issue when tabbar is displayed then search bar is covered by tabbar. See below screenshots. is it possible to move searchBar position down if tabbar gets displayed?
let searchViewController = VVSearchViewController()
let searchController = UISearchController(searchResultsController: searchViewController)
searchViewController.searchViewController = searchController
searchController.searchResultsUpdater = searchViewController
searchController.obscuresBackgroundDuringPresentation = true
let searchPlaceholderText = "Search"
searchController.searchBar.placeholder = searchPlaceholderText
searchController.searchBar.tintColor = UIColor.black
searchController.searchBar.barTintColor = UIColor.black
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.keyboardAppearance = .dark
searchController.view.backgroundColor = UIColor.black
searchController.definesPresentationContext = true;
UISearchContainerViewController(searchController: searchController)
It is possible.
It took me a while but my idea was to add the search controller into a "container" controller with constraint at the top. Nothing will appear if you try adding UISearchController as child view controller into the container. UISearchContainerViewController doesn't work as well. But a navigation controller with UISearchContainerViewController as root works. Here is my code:
// Create the search controller and it's results controller
let resultsController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SearchResultsViewController") as! SearchResultsViewController
let searchController = UISearchController(searchResultsController: resultsController)
searchController.searchResultsUpdater = resultsController
// Customize it
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [.foregroundColor: UIColor.text]
searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchController.searchBar.tintColor = .text
searchController.searchBar.barTintColor = .text
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.keyboardAppearance = .dark
// Embed it in UISearchContainerViewController
let searchContainerViewController = UISearchContainerViewController(searchController: searchController)
// Make UISearchContainerViewController root controller of a navigation controller
let navController = UINavigationController(rootViewController: searchContainerViewController)
// And a container to hold everything
let containerViewController = UIViewController()
// Do a standard child add of navController into containerViewController
navController.loadViewIfNeeded()
navController.viewWillAppear(false)
navController.willMove(toParent: containerViewController)
containerViewController.view.addSubview(navController.view)
navController.view.frame = containerViewController.view.bounds
// Add your constraints. In this case I just want the search bar to be 150 px down.
NSLayoutConstraint.activate([
navController.view.topAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.topAnchor, constant: 150),
navController.view.leftAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.leftAnchor),
navController.view.bottomAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.bottomAnchor),
navController.view.rightAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.rightAnchor)
]) containerViewController.addChild(navController)
containerViewController.addChild(navController)
navController.didMove(toParent: containerViewController)
navController.viewDidAppear(false)
// And from here use the containerViewController as normal to display a search into your app.
Note: Without passing the viewDidAppear on the navController this will not work.
Note 2: I tested this on tvOS 13 and 14 only.
You can find exactly the same case in the tab Search of the application "App Store".
This is because in tvOS the content of a viewController is not supposed to react to the visibility of the tab bar. The tab bar is presented instead on top of it, overlapping.
tvOS Human Interface GuideLines for Tab Bars:
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/tab-bars/