Xcode: Interface Builder using wrong destination to render IBDesignable

Environment

  • macOS: 10.15.3
  • Xcode: 11.3.1
    • Swift: 5.1
    • Application Target: macOS

Background

I have an IBDesignable control based on NSView (or UIView depending on the desired target). I have packaged it using Package Manager as follows:

// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "MyControl",
    platforms: [
        .macOS(.v10_13),
        .iOS(.v10)
    ],
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "MyControl",
            targets: ["MyControl"]),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages which this package depends on.
        .target(
            name: "MyControl",
            dependencies: []),
        .testTarget(
            name: "MyControl Tests",
            dependencies: ["MyControl"]),
    ]
)

As part of "MyControl", I have the following typealiases based on the desired destination Target

#if os(macOS)
    import AppKit
    public typealias QJViewController = NSViewController
    public typealias QJColor = NSColor
    public typealias QJFont = NSFont
    public typealias QJView = NSView
#elseif os(iOS) || os(tvOS)
    import UIKit
    public typealias QJViewController = UIViewController
    public typealias QJColor = UIColor
    public typealias QJFont = UIFont
    public typealias QJView = UIView
#endif

The Package compiles successfully; the control imports into my destination project correctly; everything compiles and functions as expected in the destination project.

The Problem

When I setup the control in InterfaceBuilder, it fails to render with the following error:

enter image description here

To reiterate: My Target is not appleTV, it is macOS. Regardless of what I do, IB wants to render this package, and hence my control, with AppleTV as the destination. Given the typealiases I use above, the control fails to render correctly because (obviously) macOS knows nothing about UIColor, UIFont, UIView, UIViewController.

Question

Is there a way to force IB to use a particular destination when rendering a control? If not, is there something I am missing from my project setup? Like I said, the control works as expected; I would just like it to render in IB.

You might get better results for your question over at the Apple Developer forums, StackOverflow, or the Internet in general. This question relates to Xcode, not the Swift language.

Hey Mike, I stumbled across this post of yours when looking for answers to a very similar problem. I'm running Xcode 11 and have some IBDesignables. I'm seeing Xcode try to build the Designables for tvOS even though I'm only targeting iOS. From what Jonathan Prescott mentioned, this doesn't seem like the right place to ask the question, so .....

Were you able to find an answer elsewhere? Many thanks.

-- Bennett

1 Like