I dragged and dropped progressindicator from main.xib on to a webview .
I need to show NSProgressIndicator on top of webview , instead of showing on the same webview.
The main idea is to stop the enduser to access webview until and unless NSProgressIndicator.stopAnimation(self) is done.
Can someone help me on this .
//In order to show a modelpanel on top of appdelegate.swift we need to //follow two steps.
//step1: create a cocoa class from NSWindowController as below.
import Cocoa
class ManuModalController: NSWindowController
{
#IBOutlet weak var progressIndicator1: NSProgressIndicator!
var mainW: NSWindow = NSWindow()
override init()
{
super.init()
}
override init(window: NSWindow!)
{
super.init(window: window)
}
required init?(coder: (NSCoder!))
{
super.init(coder: coder);
}
override func windowDidLoad()
{
super.windowDidLoad()
}
func beginSheet(mainWindow: NSWindow)
{
self.mainW = mainWindow;
NSApp.beginSheet(self.window!, modalForWindow: self.mainW, modalDelegate: self, didEndSelector:nil, contextInfo: nil);
progressIndicator1.startAnimation(self);
}
#IBAction func btnClicked(sender: AnyObject)
{
self.endSheet();
}
func endSheet()
{
NSApp.endSheet(self.window!);
self.window!.orderOut(mainW);
}
}
//step2 : create the object of modalcontroller in appdelegate.swift as below
var mdlwin = ManuModalController(windowNibName: "ManuModalController");
mdlwin.beginSheet(self.window);//displays the modalpanel
mdlwin.endSheet(); //closes the modal panel
Related
I can't figure out the proper way to call a function (with an IBOutlet variable inside of it) from another class. Basically after I click on the "Show Window" button, a custom alert view (container view) appears,
but when I click on the "Close" button, I want the alert view to disappear. Could someone please help me? Thanks, here's the code:
ViewController (main view):
import UIKit
class ViewController: UIViewController {
#IBOutlet var background: UIView!
#IBOutlet var windowView: UIView!
#IBAction func showWindowBtn(_ sender: Any) {
view.addSubview(windowView)
windowView.center = view.center
openAnimation()
}
// viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
background.alpha = 0
windowView.alpha = 0
}
// ---------- functions ----------- \\
// openAnimation
func openAnimation () {
UIView.animate(withDuration: 0.3) {
self.background.alpha = 1
self.windowView.alpha = 1
}
}
// closeAnimation
func closeAnimation () {
UIView.animate(withDuration: 0.3) {
self.background.alpha = 0
self.windowView.alpha = 0
}
}
}
ViewController 2 (alert view):
import UIKit
class ViewController2: UIViewController {
#IBAction func closeBtn(_ sender: Any) {
/*
In here, I want to access ViewController's 'closeAnimation()' function
without getting the 'unexpectedly found nil while unwraping an optional value'
error
*/
}
override func viewDidLoad() {
super.viewDidLoad()
// some code
}
}
I want to trigger Navigation controller to some other screen when i press the button in UIView class. How can i do this?
//Code for UIView Class in Which Button Iboutlet is created
import UIKit
protocol ButtonDelegate: class {
func buttonTapped()
}
class SlidesVC: UIView {
var delegate: ButtonDelegate?
#IBAction func onClickFinish(_ sender: UIButton) {
delegate?.buttonTapped()
}
#IBOutlet weak var imgProfile: UIImageView!
}
//ViewController Class code in Which Button Protocol will be entertained
class SwipingMenuVC: BaseVC, UIScrollViewDelegate {
var slidesVC = SlidesVC()
override func viewDidLoad() {
super.viewDidLoad()
slidesVC = SlidesVC()
// add as subview, setup constraints etc
slidesVC.delegate = self
}
extension BaseVC: ButtonDelegate {
func buttonTapped() {
self.navigationController?.pushViewController(SettingsVC.settingsVC(),
animated: true)
}
}
A more easy way is to use typealias. You have to write code in 2 places. 1. your viewClass and 2. in your View Controller.
in your SlidesView class add a typealias and define param type if you need otherwise leave it empty.
class SlidesView: UIView {
typealias OnTapInviteContact = () -> Void
var onTapinviteContact: OnTapInviteContact?
#IBAction func buttonWasTapped(_ sender: UIButton) {
if self.onTapinviteContact != nil {
self.onTapinviteContact()
}
}
}
class SwipingMenuVC: BaseVC, UIScrollViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let slidesView = SlidesView()
slidesView.onTapinviteContact = { () in
// do whatever you want to do on button tap
}
}
You can use the delegate pattern to tell the containing ViewController that the button was pressed and let it handle whatever is needed to do next, The view doesn't really need to know what happens.
A basic example:
protocol ButtonDelegate: class {
func buttonTapped()
}
class SomeView: UIView {
var delegate: ButtonDelegate?
#IBAction func buttonWasTapped(_ sender: UIButton) {
delegate?.buttonTapped()
}
}
class ViewController: UIViewController {
var someView: SomeView
override func viewDidLoad() {
someView = SomeView()
// add as subview, setup constraints etc
someView.delegate = self
}
}
extension ViewController: ButtonDelegate {
func buttonTapped() {
self.showSomeOtherViewController()
// or
let vc = NewViewController()
present(vc, animated: true)
}
}
I have a button in a subview called UIViewControllerB. Someone who taught me how to capture click event in UIViewControllerB will add a new view to UIView in UIViewcontroller A under string as my code.
This is the button in ViewControllerB displayed in UIView in UIViewController A
#IBAction func button_complate(sender: AnyObject) {
NSLog("aaa", "bbb")
}
Here is the UIViewControllerA containing UIView
#IBOutlet weak var addview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
try code:
class UIViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func addView(/*param */) {
// do something
}
// when push to UIViewControllerB set install for viewcontrollerA
private func goToScreenB(){
let viewB = UIViewControllerB()
viewB.viewcontrollerA = self
self.navigationController?.pushViewController(viewB, animated: true)
}
}
class UIViewControllerB: UIViewController {
// In UIViewControllerB create a install of UIViewControllerA
var viewcontrollerA : UIViewControllerA?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button_complate(sender: AnyObject) {
self.viewcontrollerA?.addView()
}
}
I'm busy making an app with an account page. I want that users can logon via that page and as soon as they have done so successfully that the page reloads to display their account information rather than the standard message stating that they have to logon to make use of the page.
However when I get sent back to the account page from logging on the view doesn't really update. So therefore I am wondering if I can't reload the view after certain buttons are pressed that can check again wether the user is logged on or not and deal accordingly.
if you want to trigger layouting or just drawing there is setNeedsLayout and setNeedsDisplay
There is no built-in method to reload custom data (on iOS)
so do a reload and inside a reload -- call setNeedsDisplay
import UIKit
protocol MyViewDelegate {
func viewString() -> String;
}
class MyView : UIView {
var myViewDelegate : MyViewDelegate?
private var str : String?
func reloadData() {
if myViewDelegate != nil {
str = myViewDelegate!.viewString()
}
self.setNeedsDisplay()
}
override func drawRect(rect: CGRect) {
UIColor.whiteColor().setFill()
UIRectFill(self.bounds)
if str != nil {
let ns = str! as NSString
ns.drawInRect(self.bounds, withAttributes: [NSForegroundColorAttributeName: UIColor.blueColor(), NSFontAttributeName: UIFont.systemFontOfSize(10)])
}
}
}
class ViewController: UIViewController, MyViewDelegate {
func viewString() -> String {
return "blabla"
}
var v : MyView!
override func viewDidLoad() {
super.viewDidLoad()
v = MyView(frame: self.view.bounds)
self.view.addSubview(v)
v.myViewDelegate = self;
}
override func viewWillAppear(animated: Bool) {
v.reloadData()
}
}
In Swift use this,
If you wants to reload the UIView present in the viewController just use NotificationCenter.
In ViewController class add this in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
//Trigger notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "update"), object: nil)
}
In UIView class add Observer for the notification
required init?(coder aDecoder: NSCoder) {
//Add Observer
NotificationCenter.default.addObserver(self, selector: #selector(updateList), name: NSNotification.Name(rawValue: "update"), object: nil)
}
#objc func updateList(){
//write Reload data here......
tableView.reloadData()
}
The Swift have really advanced itself and for many people if they don't know we can refresh the whole view with just one simple line of code.
viewWillAppear(true)
I have a View. In this view, I have a Container View. And in the ContainerView I have a button.
When I am touching the button of the ContainerView, I want the ContainerView become hidden.
I want to do something like that :
class ContainerView: UIViewController {
#IBAction func closeContainerViewButton(sender: AnyObject) {
//I try this : self.hidden = false
//or this : self.setVisibility(self.INVISIBLE)
}
}
Any idea how do it?
There are serval ways but here is the easiest one, not prettiest though. You should really use delegates but this is a hacky way to get started. Just create a global variable of the class that holds the container (startController in this case). Then call it from your other view controller (MyViewInsideContainer) and tell it to hide the view you´re in. I have not run this code but it should work.
var startController = StartController()
class StartController:UIViewController {
#IBOutlet var myViewInsideContainerView: UIView
....
override func viewDidLoad() {
super.viewDidLoad()
startController = self
}
func hideContainerView(){
self.myContainerView.hidden = true
}
}
class MyViewInsideContainer:UIViewController {
...
#IBAction func hideThisView(sender: AnyObject) {
startController.hideContainerView()
}
}
i think a cleaner solution is to use delegation:
in the ParentViewController
class ParentViewController: UIViewController ,ContainerDelegateProtocol
{
#IBOutlet weak var containerView: UIView!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
//check here for the right segue by name
(segue.destinationViewController as ContainerViewController).delegate = self;
}
func Close() {
containerView.hidden = true;
}
in the ContainerViewController
protocol ContainerDelegateProtocol
{
func Close()
}
class ContainerViewController: UIViewController {
var delegate:AddTaskDelegateProtocol?
#IBAction func Close(sender: AnyObject) { //connect this to the button
delegate?.CloseThisShit()
}