I am making a financial app. I have a UINavigationController, wrapped around the UIViewController. The large titles in the navigation bar are turned on. I am using a UITableView as a scroller, and a UIImageView with a png image as a background. Now as I scroll the UITableView down, I expect the large titles shift to regular titles. By the way, my navigation bar is somewhat transparent. I am not even trying to ask you guys how to fix the transition from the large titles to regular titles in the navigation bar as I am sure that no one knows how to do that. At least none of the fixes that have been proposed here for 7 years could fix it for me. And as I learned here: https://www.reddit.com/r/iOSProgramming/comments/7k60dl/ios11_large_titles_not_shrinking_tip/, whoever is still trying to figure this problem out, should just abandon all hopes. IT IS IMPOSSIBLE TO PLACE UIIMAGEVIEWE BEHIND THE TABLE VIEW AND EXPECT THE LARGE TITLES TRANSITION TO WORK NORMALLY.
Therefore, I pinned the table to the master view and applied the background to the table directly. The transition started working, but very slowly and with hiccups. But that is not the problem. Since I have a transparent navigation bar, I want the background to occupy the entire screen, and the UITableView to be pinned to a safe area from the top, so nothing goes behind the navigation bar.
This is where the conundrum is. If I pin the background image to the table and make the table pinned to a safe area, whenever I scroll down, the large titles shrink, but the background image is stretching like Stretch Armstrong. It looks stupid. But If I pin the table view to the super view, the scrollable content shows through the navigation bar.
Question: How do I pin the table to a safe area, but make the background extend to super view, and have the large titles/regular titles transition still in place? So that the content doesn’t show behind the transparent navigation bar. Here’s my viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(masterTableViewAsViewScroller)
masterTableViewAsViewScroller.delegate = self
masterTableViewAsViewScroller.dataSource = self
let masterTableViewBackground = UIImageView(image: UIImage(named: "moneyBg"))
masterTableViewBackground.frame = self.masterTableViewAsViewScroller.frame
self.masterTableViewAsViewScroller.backgroundView = masterTableViewBackground;
masterTableViewAsViewScroller.pin(to: view)
title = "Some Title"
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
let image = UIImage.imageFromColor(color: UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.4))
self.navigationController?.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
self.navigationController?.navigationBar.barStyle = .default
}
Also, my extensions, which are placed in a separate swift file:
import UIKit
extension UIView {
func pin(to superView: UIView) {
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superView.topAnchor).isActive = true
leadingAnchor.constraint(equalTo: superView.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: superView.trailingAnchor).isActive = true
bottomAnchor.constraint(equalTo: superView.bottomAnchor).isActive = true
}
}
extension UIImage{
static func imageFromColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image! } }
By the way, this is a redo for safe area pinning that I am using:
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
masterTableViewBackground.topAnchor.constraint(equalToSystemSpacingBelow: guide.topAnchor, multiplier: 1.0),
guide.bottomAnchor.constraint(equalToSystemSpacingBelow: masterTableViewBackground.bottomAnchor, multiplier: 1.0)
])
} else {
let standardSpacing: CGFloat = 8.0
NSLayoutConstraint.activate([
masterTableViewBackground.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
bottomLayoutGuide.topAnchor.constraint(equalTo: masterTableViewBackground.bottomAnchor, constant: standardSpacing)
])
}
I add gifs so you could see what I'm talking about.

