简体   繁体   中英

Accessing View Controller from another project in Swift 3

Is it possible to access a view controller from my previous project?

What I want to achieve is to use the view controller of my previous project to my new project programmatically. In Swift 3.

You can use a Framework target to contain virtually any common code you want, including UIViews.

In your Framework:

open func commonView() -> UIView {
    // code to create view or call up xib file from framework
}

In your app:

import MyFramework

class MainViewController:UIViewController {
    override viewDidLoad() {
        self.view = commonView()
    }
}

But if you want it to be a UIViewController? I'm not so sure that can easily work. Maybe if you make it a child VC of a VC in the app, of split out everything among the VC's view and it's logic. In that sort of scenario, you probably are better off with the more manual solution that @Lion gave you.

If you are interested, here's a more detailed description of setting up a Framework target from a question I answered a few weeks ago.

EDIT Based on a comment, here's a bit more that may help. First, remember my original answer included a link at the end to something that should help you set things up in Xcode. Also, the important thing - maybe the most important - is to design things properly!

Let's say you wish to have common code to add a set of buttons that look the same and that you can connect up to specific functions within a specific app.

First, recognize what you can and cannot do, due to the platform. You have Cocoa (Foundation) and Cocoa Touch (UIKit). In other words, you have an NSButton and a UIButton. I know of no way you can simply make a framework that returns a "button". (But a framework can return a Core Image filter output because that is platform agnostic.)

Restricting things to UIKit, let's talk storyboards and view controllers. I'm finding much confusion on the latter. There's a huge difference between "views" and "view controllers". Yesterday I made several edits to a question because of this. UIViews are the base of just about any control in UIKit. UIViewControllers contain the logic to work with the views. (BTW, this is MVC 101.)

Storyboards are something specific to Xcode, and as such, I'm not a good source of how "reusable" you can make them. They may be something you can do - after all in the end they are a specific XML format that Xcode uses.

But while you probably cannot use a UIViewController as a return in a framework call (at least not easily), you can use any UIView - and their subclasses. And guess what? UIButton is such a thing.

Swift introduces much to a framework. Extensions and convenience initializers are two features. Let's say you put this into a framework:

extension UIButton {
    convenience public init(
        title:String,
        titleColor:UIColor,
        titleFontSize:CGFloat,
        image:UIImage,
        titleEdgeInsets:UIEdgeInsets,
        imageEdgeInsets:UIEdgeInsets,
        tintColor:UIColor,
        backgroundColor:UIColor,
        borderColor:CGColor,
        borderWidth:CGFloat,
        cornerRadius:CGFloat
        ) {
        self.init(type: .system)
        self.setTitle(title, for: .normal)
        self.setTitleColor(titleColor, for: .normal)
        self.titleLabel?.font = UIFont.systemFont(ofSize: titleFontSize)
        self.setImage(image, for: .normal)
        self.titleEdgeInsets = titleEdgeInsets
        self.imageEdgeInsets = imageEdgeInsets
        self.tintColor = tintColor
        self.backgroundColor = backgroundColor
        self.layer.borderColor = borderColor
        self.layer.borderWidth = borderWidth
        self.layer.cornerRadius = cornerRadius
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

If you combine that with this:

public func returnImage(_ named:String) -> UIImage {
    let myBundle = Bundle.init(identifier: "com.company.framework")
    let imagePath = (myBundle?.path(forResource: "images", ofType: "bundle"))! + "/" + named
    let theImage = UIImage(contentsOfFile: imagePath)
    return theImage!
}

[Replace "com.company.name" with your Framework ID, and "images" with the name of your bundle]

And you can do this in your app, as long as you imported your framework:

let openCamera = UIButton(
    title:              "Camera",
    titleColor:         UIColor.yellow,
    titleFontSize:      15,
    image:              returnImage("Camera"),
    titleEdgeInsets:    UIEdgeInsets(top: 0, left: -51, bottom: -49, right: 0),
    imageEdgeInsets:    UIEdgeInsets(top: 0, left: 0, bottom: 23, right: -51),
    tintColor:          UIColor.yellow,
    backgroundColor:    UIColorFromRGB(0x1F1F1F),
    borderColor:        UIColor.yellow.cgColor,
    borderWidth:        2,
    cornerRadius:       10)

I'm still learning subtleties with Swift and frameworks... optionals and such. But you can also do this in your framework:

public class ToolBoardCloseButton: UIButton {
    convenience init(
        tag     :Int,
        target  :Any,
        action  :Selector
        )
    {
        self.init(frame: CGRect.zero)
        self.backgroundColor = sgRed
        self.setTitle("Close", for: .normal)
        self.tintColor = UIColor.white
        self.layer.cornerRadius = 5
        self.layer.borderColor = UIColor.white.cgColor
        self.layer.borderWidth = 1
        self.tag = tag
        self.addTarget(target, action: action, for: .touchUpInside)
    }
}

And so that means this in your app:

closeButton = ToolBoardCloseButton(tag: tag, target: target, action: hideAction)

Of course, if you have control on this, make your target and action optional (if you need, I didn't). That way - as long as you code for it - you can make them optional in your calls.

Last note. In my framework the UI logic behind "hideAction" is there as part of the ToolBoard class, which is a subclass of UIView. All my app has in the view controller is (1) instantiating the ToolBar, tool bar buttons, and boards (along with their sizes), (2) creates the close button and the call to the framework to close it, and that leave (3) code that is app-specific. While you may not find a way to move a UIViewController into a framework call, you should be able to move all your common code and views into one.

This is not possible that you can open a viewcontroller of another project from you current project. For that you have to add that specific viewcontroller in to your project! You can copy and paste that viewcontroller and it's class easily from one project to another! and yes you can open another installed application from your app(but this is not you want as i understood from your question)!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM