Crash when using loadNibNamed - swift

This is my code:
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
let mainBundle = Bundle.main
mainBundle.loadNibNamed("iconView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
I copied it from step 8 in this tutorial that I've seen (I only changed the name in the code to my xib file: "iconView").
But for some reason it fails:
I already tried all of the solutions in stackoverflow, but nothing helped me.
Here is my xib file:
I really don't know what to do.
I'm using Xcode 12 beta 6, iOS 14 beta 6
UPDATE
Okay, a lot of people saied in the comments of the tutorial that
This causes an infinite-loop calling commonInit().
So now I know what the issue is, but I still don't know how to solve it. Any ideas?

You probably have to remove Class from your View.
First select your View (in your case iconView):
and then clear whatever there is in the class field:

Related

Xcode 13 convenience init compiler issue

Before I updated to Xcode 13 the code below worked fine in another custom UIView created in Xcode 12.
I created this new custom view and the compiler gives the following contradictory errors with reference to the convenience init
Overriding declaration requires an 'override' keyword
'init(frame:)' has already been overridden
Why is Xcode 13 reporting this error in the new custom class but not the identical one created in Xcode 12?
class OptionsPanel: UIView {
override init(frame : CGRect) {
super.init(frame : frame)
}
convenience init(frame: CGRect) {
self.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
That was the problem. In the other custom view I had other parameters in the convenience init convenience init(frame: CGRect, packages: [Purchases.Package], testing: Bool).
I did try other parameters in this one thinking it might be the problem but had all sorts of issues with the pods Xcode indexing forever until I created a new project and iPhone 13 simulators not showing up.... so it got lost in all that fire fighting!
Thank you Sweeper, Duncan C & Bhawin Ranpura.
I have been asked to edit by Community.
The problem as exactly as answer given -
The convenience init cannot be identical to init. ie
override init(frame : CGRect) {
super.init(frame : frame)
}
convenience init(frame: CGRect) {
self.init(frame: frame)
}
Is rejected by the compiler.

Subclassed UIButton title font size changing unexpectedly

I'm using protocol delegate to set the title of a UIButton. However, somewhere along the line the font size is unexpectedly changing from 14 to 17. I've tried subclassing the button to keep the font at size 14, but clearly something is going wrong. It's been suggested that perhaps there's a conflict somewhere with the font size. However, I can't find any code that creates conflict.
Subclassed button:
import UIKit
class typeButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
titleLabel?.font = UIFont(name: "Helvetica", size: 14)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Protocol extension:
extension ObservationDetailViewController: MushroomTypeDelegate {
func didSelectMushroom(name: String) {
typeButton.setTitle(name, for: .normal)
observation?.type = name
}
} // End of Extension
The button is classed via Storyboard. If I place a breakpoint on the line setting the button title typeButton.setTitle(name, for: .normal) it shows the font at size 14 . Yet, as I move past the breakpoint the font is unexpectedly changed to a larger size. I was able to use attributed text, & setAttributedTitle to fix this, but I'm curious why the font size is being changed.
Link to GitHub file
Try setting the font size in init?(coder aDecoder: NSCoder) since you classed the button from storyboard:
class TypeButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
titleLabel?.font = UIFont(name: "Helvetica", size: 14)
}
}
And make sure the font name is correct.

NSTouchBar not releasing last touched view

I am making an app which uses the NSTouchBar.
The touchbar is made by the NSWindowController.makeTouchBar()method.
In this touchbar I can place NSCustomTouchBarItems.
I have made two NSCustomTouchBarItems.
The first one sets a view to a default ui button, with this:
let item001 = NSCustomTouchBarItem(identifier: someIdentifier)
item001.view = NSButton(title: "myButton", target: nil, action: nil)
The second one sets a viewController, with this:
let item002 = NSCustomTouchBarItem(identifier: someIdentifier)
item002.viewController = TestViewController()
The TestViewController only loads a simple view inside its loadView()
method.
class TestViewController: NSViewController {
override func loadView() {
self.view = TestView001(frame: NSRect(x: 0, y: 0, width: 100, height: 30))
}
}
The TestView001 only creates a background color so you can see it.
TestView001 has the following code:
class TestView001: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
print("TestView001.init()")
// Create a background color.
self.wantsLayer = true
self.layer?.backgroundColor = NSColor.green.cgColor
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
All of this works perfectly.
But when I have touched the second item inside the touchbar,
and then close my app's window.
The windowController and everything else is nicely released
from memory.
But I can still see that TestView001 is in memory and not being
released.
When using a standard ui button like in item001, then you don't
have this problem.
It looks like some NSTouch still has a reference to the view
if you look at this image:
However, I do not completely understand this image.
What is the best way of solving this.
Thanks in advance.

What to use as NSCoder to initialize a View?

Hey guys I created a new custom View Class and now I want to build a instance of it, I initialized it with the following code:
required init?(coder aCoder: NSCoder) {
super.init(coder: aCoder)
tapRecognizer = UITapGestureRecognizer(
target: self, action: #selector(handleBarTap))
addGestureRecognizer(tapRecognizer)
}
deinit {
removeGestureRecognizer(tapRecognizer)
}
And this is the instance, but what can I use as coder?
lazy var chartView = TutorialChartView(coder: )
Thanks in advance!
When you say View, do you mean UIView? The problem is that that's the wrong initializer. init(coder:) is not something you call; it's a process initiated by the storyboard when there is one of these things in the storyboard and you load that view controller.
The code UIView designated initializer is init(frame:). Implement that and call it, and you're all set.
(You may also have to provide an implementation of init(coder:) but it should just throw a fatalError, because you do not expect to be called this way.)
You should cannot use coder as initializer for creating class, use frame instead, here is your code written in frame-style initializing.
override init(frame: CGRect) {
super.init(frame: frame)
tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleBarTap))
addGestureRecognizer(tapRecognizer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Here is how you use it:
lazy var chartView = TutorialChartView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)

swift IBDesignable view not show in storyboard

I want to custom a 5-star UIView,also I want it to be render in storyboard. So I decide to use #IBDesignable and #IBInspectable.The following is my code.
import UIKit
#IBDesignable
class RatingView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpView()
}
func setUpView() {
let imageView = UIImageView(frame:CGRectMake(0, 0, 50,50))
imageView.image = UIImage(named: "star")
addSubview(imageView)
}
}
And then in my storyboard , I pull a UIView into my canvas,and set Custom class to my custom view as RatingView.The compiler starts to compile storyboard file and I just wait for the custom view to be renderd in canvas.Here is the screenshot.
The state is "up to date",but the view has not been renderd.The view is just staying white,what I want to see is the image I add to the parent view.
When I use UILabel instead of UIImageView, the label is renderd in the canvas but not the UIImageView,how can I render my lovely star image in my canvas.(Images.xcassets has star.png file)
use UILabel instead of UIImageView
func setUpView() {
let label = UILabel(frame: CGRectMake(0, 0, 50, 50))
label.text = "text"
addSubview(label)
}
result:
I was trying to do the same exact thing. You need to put the view in a framework. As #Benson Tommy said in the comments take a look at WWDC 2014 session 411.
Here is a link to the session:https://developer.apple.com/videos/wwdc/2014/#411
Here is a link to the transcript of the session: http://asciiwwdc.com/2014/sessions/411