iOS 11 - Navigationbar large title custom offset
Asked Answered
C

5

15

Is it possible to change the x-offset of the large navigation bar title? I would like to change the x-offset to 36pt.

The navigation bar

Cronyism answered 24/10, 2017 at 11:31 Comment(0)
A
32

I just discovered in the latest version of iOS 12, if you simply modify the layoutMargins property of the UINavigationBar, this will affect the large title.

let navigationBar = navigationController.navigationBar
navigationBar.layoutMargins.left = 36
navigationBar.layoutMargins.right = 36

I tried the solution mentioned here about using a custom NSMutableParagraphStyle. That does indeed work, but because it stretches the UILabel view that the large title is made of, when you swipe downwards, the subtle animation it plays where the text grows slightly becomes quite distorted.

Alcheringa answered 4/3, 2019 at 13:30 Comment(2)
Great tip. This also works if you are using a search bar: searchController.searchBar.layoutMargins.left = X.Citrin
Great point about NSMutableParagraphStyle approach issues. Thank you!Suffrage
N
9

You can add additional offset this way:

if #available(iOS 11.0, *) {
    let navigationBarAppearance = UINavigationBar.appearance()
    let style = NSMutableParagraphStyle()
    style.alignment = .justified
    style.firstLineHeadIndent = 18
    navigationBarAppearance.largeTitleTextAttributes = [NSAttributedStringKey.paragraphStyle: style]
}
Newsworthy answered 2/3, 2018 at 20:24 Comment(1)
This broke for me with long titles. I added style.lineBreakMode = NSLineBreakByTruncatingTail;Tallman
S
1

You can't. You need to write your own NavigationController, by subclassing the UINavigationController for that.

Street answered 24/10, 2017 at 14:53 Comment(0)
O
0

You'll have to subclass the UINavigationBar, then override the draw method, and inside make the changes. Have a look at my working example and then adjust the offset/styles as you need:

    override func draw(_ rect: CGRect) {
    super.draw(rect)

    self.backgroundColor = UIColor.white
    let largeView = "_UINavigationBarLargeTitleView"
    let labelcolor = UIColor(red: 36.0/255.0, green: 38.0/255.0, blue: 47.0/255.0, alpha: 1.0)

    for view in self.subviews {
        if largeView.contains(String(describing: type(of: view))) {
            for v in view.subviews {
                if String(describing: type(of: v)) == "UILabel" {
                    var titleLabel = v as! UILabel
                    var labelRect = titleLabel.frame
                    let labelInsets = UIEdgeInsets(top: 10, left: 13, bottom: 0, right: 0)
                    let attrText = NSMutableAttributedString(string: "Jobs", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProDisplay-Heavy", size: 30)!, NSAttributedStringKey.foregroundColor: labelcolor])

                    labelRect.origin.y += 20
                    let newLabel = UILabel(frame: labelRect)
                    newLabel.attributedText = attrText
                    titleLabel.text = ""
                    if labelRect.origin.y > 0 {
                        titleLabel = newLabel
                        titleLabel.drawText(in: UIEdgeInsetsInsetRect(labelRect, labelInsets))
                    }
                }
            }
        }
    }
}
Outstare answered 23/3, 2018 at 10:20 Comment(0)
L
0

SwiftUI

You can adjust the layout margin across your entire app in the AppDelegate

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
    ) -> Bool {
        // Adjust left margin
        UINavigationBar.appearance().layoutMargins.left = 36
        
        return true
    }
}

@main
struct testApp: App {
    // Attach AppDelegate
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Lanham answered 8/12, 2022 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.