(Xcode / Swift) How to hide toolbar when scrolling down UIWebView? - xcode

I have a UIWebView in my ViewController and a navigation controller embedded in my ViewController. In my navigation controller, I selected "Show Toolbar" and "Hide Bars on Swipe" but the Toolbar doesn't hide. It only works when "Show Navigation Bar" is selected with the Toolbar.
Is there anyway to have the Toolbar hide on swipe when scrolling down the UIWebView?
Thank you in advanced.

You can use UIScrollViewDelegate for that.
Here is example code for hide navigation bar and tool bar with scroll:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var toolBar: UIToolbar!
#IBOutlet weak var webV: UIWebView!
var lastOffsetY :CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
webV.scrollView.delegate = self
let url = "http://apple.com"
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!)
webV.loadRequest(request)
}
//Delegate Methods
func scrollViewWillBeginDragging(scrollView: UIScrollView){
lastOffsetY = scrollView.contentOffset.y
}
func scrollViewWillBeginDecelerating(scrollView: UIScrollView){
let hide = scrollView.contentOffset.y > self.lastOffsetY
self.navigationController?.setNavigationBarHidden(hide, animated: true)
toolBar.hidden = hide
}
}

Related

Replace NSViewController under Swift2 Storyboard MAC OSX

I am new to Mac OSX and with Apple promoting the fact that the bodies of code are becoming similar decided to tell the folk I am writing code for we should be able to do a Mac OSX version. iPhone and iPad versions are all good and about to release second version so no issues there.
So I am subclassing NSWindowController to get access to the Toolbar and worked out how to remove and add items on the toolbar, but for the life of me I can not get one NSViewController (firstViewController) to dismiss and bring up the second NSViewController (secondViewController) in the same NSWindowController.
So the 2 issues are that
1. I want to be able to performSegueWithIdentifier from the first NSViewController in code and
2. bring up the second NSViewController by replacing the first NSViewController in the same NSWindowController.
If I add a button to the firstViewController and put a segue to the secondViewController then when I select the button the secondViewController comes up just fine but in a seperate window not the same NSWindowController that I want it to and the firstViewController does not get replaced but stays in the NSWindowController.
So I know the segue idea will work but its not working in code and when I do insert the segue from a button it works but into a seperate NSViewController that is not part of the NSWindowController.
I am trying to find some programming guide from Apple on the issue but no luck so far.
Here is an overview from my Storyboard:
Here is my NSWindowController subclassed and the func loginToMe2Team is trigger from the NSToolBar and its working just find as the print statements show up on the console.
import Cocoa
class me2teamWindowsController: NSWindowController {
#IBOutlet var mySignUp : NSToolbarItem!
#IBOutlet var myToolbar : NSToolbar!
let controller = ViewController()
override func windowDidLoad() {
super.windowDidLoad()
print("window loaded")
}
override func windowWillLoad() {
print("window will load")
}
#IBAction func logInToMe2Team(sender: AnyObject){
controller.LogIn() //THIS IS THE FUNC I AM TESTING WITH
}
#IBAction func signUpToMe2Team(sender: AnyObject){
controller.signUp()
}
Here is my NSViewController subclassed with the func LogIn. Its getting selected just fine but the performSegueWithIdentifier is not. And I did cut and past the Identifier to make absolutely sure it was the same.
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var theWebPage: WebView!
#IBOutlet weak var progressIndicator: NSProgressIndicator!
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://thewebpage.com.au"
self.theWebPage.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: urlString)!))
}
override func viewDidAppear() {
}
func LogIn() {
print("I logged in")
self.performSegueWithIdentifier("goToTeamPage", sender: self)
//THIS IS THE BIT THATS NOT WORKING
}
func signUp() {
print("I have to sign up now")
}
override var representedObject: AnyObject? {
didSet {
}
}
func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)
{
self.progressIndicator.startAnimation(self)
}
func webView(sender: WebView!, didFinishLoadForFrame frame: WebFrame!)
{
self.progressIndicator.stopAnimation(self)
}
}
You need to use a custom segue class (or possibly NSTabViewController if it’s enough for your needs). Set the segue’s type to Custom, with your class name specified:
…and implement it. With no animation, it’s simple:
class ReplaceSegue: NSStoryboardSegue {
override func perform() {
if let src = self.sourceController as? NSViewController,
let dest = self.destinationController as? NSViewController,
let window = src.view.window {
// this updates the content and adjusts window size
window.contentViewController = dest
}
}
}
In my case, I was using a sheet and wanted to transition to a different sheet with a different size, so I needed to do more:
class ReplaceSheetSegue: NSStoryboardSegue {
override func perform() {
if let src = self.sourceController as? NSViewController,
let dest = self.destinationController as? NSViewController,
let window = src.view.window {
// calculate new frame:
var rect = window.frameRectForContentRect(dest.view.frame)
rect.origin.x += (src.view.frame.width - dest.view.frame.width) / 2
rect.origin.y += src.view.frame.height - dest.view.frame.height
// don’t shrink visible content, prevent minsize from intervening:
window.contentViewController = nil
// animate resizing (TODO: crossover blending):
window.setFrame(window.convertRectToScreen(rect), display: true, animate: true)
// set new controller
window.contentViewController = dest
}
}
}

Swift: Setting NSStatusBarButton to highlight once NSPopover is displayed

I have an NSPopover connected to the NSView of a window. Currently I have a NSStatusItem that displays a NSStatusMenu. When you click a certain option in that menu I set the menu to nil and then display the NSPopover. The problem is I want the status bar button to remain highlighted when the NSPopover is displayed, but it only flashes highlight when I click the button to open the NSPopover. I have tried statusItem.button?.highlight(true) to no avail, and it seems changing the button type does not do anything either. Any ideas? Thanks. Also, any way to make the NSView inside the popover or more specifically the text field in the NSView selected once the NSPopover is opened? I have the popover behavior set to transient but it will only close if you click on the popover first, then outside the popover.
#IBOutlet weak var mainMenu: NSMenu!
#IBOutlet weak var popover: NSPopover!
#IBOutlet weak var popoverView: NSView!
#IBOutlet weak var textField: NSTextField!
// init new menu bar item
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
// init menu bar item icon
let icon = NSImage(named: "menuIcon")
icon?.setTemplate(true) // now compatible with "dark mode"
statusItem.image = icon
statusItem.menu = mainMenu
popover.behavior = NSPopoverBehavior.Transient
//statusItem.button?.setButtonType(NSButtonType.OnOffButton)
}
#IBAction func StatusItemClicked(sender: NSButton) {
if !(popover.shown) {
popover.showRelativeToRect(sender.bounds, ofView: statusItem.button!, preferredEdge: NSMinYEdge)
}
else {
popover.close()
}
}
#IBAction func movieRegular(sender: NSMenuItem) {
statusItem.menu = nil // get rid of statusItem menu
statusItem.action = Selector("StatusItemClicked:") // func StatusItemClicked called when button clicked
StatusItemClicked(statusItem.button!) // call it so popover immediately displays first time
}

Calling popover from a menu item crash

I have a toolbar button
#IBOutlet weak var testButton: NSToolbarItem!
The button call a popover and works fine.
But if i try and call the popover from a top menu item i get a crash.
I have amended the location of the popover to appear below the testButton just as it normally would. (commented below)
#IBAction func menuPreviewAndTestAction(sender: AnyObject) {
var returnedHtmlString = checkEverythingAndCreateTheEncodedHtml(testButton)
setEncodedHtmlToPreview(returnedHtmlString)
var thebounds = self.testButton.view?.bounds // so i am givving bounds of button that narmally calls poover
testingPopover.showRelativeToRect(thebounds!, ofView: sender as NSView, preferredEdge: NSMaxYEdge) // crashes
}
Oh dear... I missed changing the ofView, all sorted with :
var thebounds = self.testButton.view?.bounds
var theview = self.testButton.view
testingPopover.showRelativeToRect(thebounds!, ofView: theview! as NSView, preferredEdge: NSMaxYEdge)

Xcode 6 interface builder, cannot link storyboard window to code

I am a relatively new developer working with swift in Xcode 6.1 beta. I am trying to make a simple application that has 2 text fields: 1 for first name, 1 for last name. When the submit button is pressed, a new window opens and displays the full name.
I have successfully gotten the application to work on a single window, with the result appearing in a third non-editable text field.
However, when I add the second view controller to the storyboard for the new window, make it launch when the button is pushed, and drag the result field into it, the application does not work.
I tried re-linking the field to my ViewController.swift (where all my code is), but it does not show up on automatic. When I open it via manual, I cannot link to the file.
original window:
http://i.stack.imgur.com/C0xui.png
new window:
http://i.stack.imgur.com/XdZ2l.png
Viewcontroller.swift:
import Cocoa
class ViewController: NSViewController {
#IBOutlet var window: NSView!
#IBOutlet weak var first: NSTextField!
#IBOutlet weak var last: NSTextField!
#IBOutlet weak var output: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btn(sender: AnyObject) {
var first = self.first.stringValue
var last = self.last.stringValue
if first.isEmpty {
self.output.stringValue = ""
}
else {
self.output.stringValue = "Hello, \(self.first.stringValue) \(self.last.stringValue)!"
}
}
override var representedObject: AnyObject? {
didSet {
}
}
}
You have to show assistant window in the menu
View > Assistant Editor > Show Assistant Editor

How can I call a function/action when a statusItem is clicked?

I have this code that opens up a popover element at the "sender" location, i.e. the button that was pressed. How can I make this function call when a statusItem is clicked, so that the popover comes down from the status/menu bar?
#IBAction func togglePopover(sender: AnyObject) {
if !(popoverIsOpen) {
myPopover.showRelativeToRect(sender.bounds, ofView: popoverButton, preferredEdge: NSRectEdge(3))
popoverIsOpen = true
}
else {
myPopover.close()
popoverIsOpen = false
}
}
I am currently using NSPopover and NSStatusItem.
edit: The changelog for Xcode 6 beta 4 added NSStatusItem.button and softly deprecated the previous form of calls like NSStatusItem.action, NSStatusItem.title, NSStatusItem.target, etc.
The documentation now reads
NSStatusItem.button
The button that is displayed in the status bar. This is created automatically on the creation of the StatusItem. Behavior customization for the button, such as image, target/action, tooltip, can be set with this property.
I was able to reach an implementation shown below, using the new NSStatusBarButton visual representation of an NSStatusBarItem. In this example, my .xib file has the NSPopover element already connected to a view, which isn't shown here.
#IBOutlet weak var myPopover: NSPopover!
var statusBar: NSStatusItem!
var popoverIsOpen = false
#IBAction func togglePopover(sender: AnyObject) {
if !(popoverIsOpen) {
myPopover.showRelativeToRect(sender.bounds, ofView: statusBar.button, preferredEdge: NSRectEdge(3))
popoverIsOpen = true
}
else {
myPopover.close()
popoverIsOpen = false
}
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
//initialize menu bar icon
statusBar = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(48))
statusBar.button.title = "Your App Title"
statusBar.button.appearsDisabled = false
statusBar.button.action = Selector("togglePopover:")
statusBar.button.target = self
}

Resources