Two Frameworks use the name for a property - swift

SwifterSwift has a property name cornerRadius.
It's an extension to UIView.
While the DropDown framework has a property name cornerRadius.
DropDown (the class) is a subclass of UIView.
It seems like xCode doesn't know which property I'm referring to.
I only imported one framework to my file but SwifterSwift's extension still takes effect.
I modified the DropDown framework and everything worked fine but then I reverted because it's not allowed and I wouldn't know how to debug any future problems.
I also tried creating a function in an extension to somehow get around this problem.
It turns out that I can't directly access DropDown's table (which is the view that we round).
I cant remove the SwifterSwift framework because it has already been used in the project that I'm working on. Although that might be the best option.
Is there a solution to this problem ?

In Swift, namespaces are implicit and belong to target it is defined. So, for your case, the workaround would be to add the target name in the property call.
SwifterSwift.cornerRadius
DropDown.cornerRadius
Let take example of String. It belongs to Swift target and so I can do this
let str = Swift.String("abc".characters)

Please follow the steps in this issue
Or upvote for adding prefix to all SwifterSwift extensions here

Related

How do I add my own properties to the Bindings Inspector in Xcode?

When editing a .xib in Xcode, I can select a view or other object, navigate to the "Bindings" tab in the Inspector, and bind its properties to properties of other objects. This is all well and good, but if I create my own subclass and add new properties, those properties won't appear in the list, and I'm having trouble finding an up-to-date solution for adding them.
I'm aware that I can create the binding at runtime using bind:toObject:withKeyPath:options:, but that doesn't seem like a very elegant solution, as it's clunkier than setting up a binding normally is, and adding glue code kind of defeats the purpose of using bindings. The only method I've seen is to create something called an IBPlugin, but I'm hearing Xcode stopped supporting IBPlugins ages ago when it and Interface Builder were merged into a single program.
So how can I do this? I tried #IBInspectable, which makes properties settable in the inspector, but it doesn't look like that makes them bindable.

Is it ok to use UIButton's .tag property for myself?

I realize that I can create a subclass of UIButton to add custom properties:
class myButton: UIButton {
var viewBounds : CGRect = .zero
...
}
However, at this moment I only need each button to store an Int, I am not using storyboards, and a lot of postings say that it's alright to use the tag property.
My question is, is this actually safe? Given possible future changes. etc. etc.? "Many postings" is not the same as an official answer, which I can't seem to find an answer to in the official documentation.
It depends on what you're looking to use the tag property for. From the UIView.tag docs, which you have likely seen:
An integer that you can use to identify view objects in your application.
</snip>
You can set the value of this tag and use that value to identify the view later.
The purpose of tag is to be an arbitrary user-settable property that you can use to differentiate between different views of the same type when you don't otherwise have a named reference to them.
UIKit itself will never set tag because the property is meant to be set by you, the app developer; however, that doesn't mean that some 3rd-party framework you're using is guaranteed not to stomp on tag values. Because tag lives in a "global" namespace of sorts (all code has equal access/knowledge to tag, unlike a property you might add yourself), different people might try to use tag for different things.
If you're creating view objects yourself, and managing the view hierarchy directly, then it's relatively safe to use tag. On the other hand, if you're getting views from another framework, or allowing another framework to manage views for you, it may use tag for its own purposes.
From your question, it appears the former is likely the case, but if you need stronger guarantees, you're better off adding another property which more directly identifies the views you'd like to be using.
You also haven't specified what you want to use tag for, necessarily, but if you just need to store an Int that's completely unrelated to identifying the button, I'd advise against using tag and instead add a semantic property that describes what you're trying to store. (Tags are also meant to be unique, which arbitrary data might not be.)

Unknown class in Interface Builder file

Why am I still getting this error when I run my iPhone app? The file is a ViewController that I have been working to delete and replace, but it just won't die. As far as I know, I don't have any reference (string or otherwise) to this file in my project.
I have deleted the related file (I'm trying to get rid of it.)
I have cleaned the project and rebuilt.
I have "Reset Content and Settings" in my simulator.
I have done a grep (grep -i -r "TheClassName" *) and nothing matches except my UserInterfaceState.xcuserstate file.
I have searched the code using XCode's Find/Replace tab.
I have double checked my Build Phases and am pretty sure it isn't in there (its a large project).
Any other ideas? I've spent way too many hours trying to figure this simple thing out; I must be missing something.
Thanks!
Check your nibs or storyboard, and make sure none of your views are set to the class!
I finally fixed the problem after trying it on multiple machines over the course of almost 2 days! I will not be thwarted!
I tracked the problem down to a call to setViewControllers on a UINavigationController which is called on initialization of the application. I was always being passed 3 objects (there are 3 panes in the navigation controller). Even though I had deleted the third object, as previously explained, three objects would always be passed in. The class type of the first two was correct, but the third would just be a UIViewController. Curiously, this view controller had a nibName which corresponded to the object file and Xib file that I had previously deleted. Of course, when view was called on this borked UIViewController, it would crash since the corresponding nib had obviously been deleted. Remember, the textual name of this object or Xib could not be found in my directory with grep, so I have absolutely no idea how in the world it came into existence when I ran my app.
So, I figured the app may not have been cleaned properly. I double and triple checked this. I even validated that my Workspace settings were correct (File->Project Settings->Advanced). The app was indeed being recompiled fresh every time.
Secondly, I started thinking that perhaps the object was being set by some other means. Working backwards, I added some breakpoints and found out that initWithCoder was being called on the parent UINavigationController--this was eventually working down to call the setViewControllers on the object and assigning the three view controllers (one of which was the offending one). I could easily see from the call stack that the Nib file that was being loaded was deserializing something offensive.
So, I started digging into my Xib file. Of course, the object name wasn't in the file (as expected since the grep didn't find anything). I deleted and recreated the portion of the Xib that included my root UINavigationController. This ended up changing the Object ID and ref within the Xib file.
Secondly, I created a new Xib and UIViewController with the same names as the one which I had previously deleted, hoping that Xcode might be happy if I created and then re-deleted them. I then compiled, re-deleted them, updated by Xib file yet again, reverified with grep that yes, indeed, nothing existed with that name.
And it worked. After spending multiple days on this issues, I'm fairly sure that there is a bug here in the interface builder, but do I want to revisit this problem to file a bug report? Absolutely not...
In my case, I solved an issue by name of Custom class name of View instead of Custom class of ViewController. By mistake i added like this for view as shown below.
It Should be for ViewController like this.
This is in my case, for you may be it's related with another component.
This happens when the view class is in a framework. Select the framework's module. Example with a CocoaPod: HSegmentControl.
Make sure when you add or rename or move files around especially in folders, that when you add them you:
A. Create Groups, not references they don't usually read in.
B. Check the boxes for the apporpriate "Product(s) or Target(s)" you want to add the source to.
Another thing to try :
I had to toggle "Inherit from Target" under the "Module" control of "Custom Class."

XCode wont let me use a Static Library View in my xib files

I created a new project of type Static Linked Library.
I have moved the code (previously working in the app) to the library leaving all the xib files in the app.
I have changed the export directory and added the library file from the derived data folder so it gets the compiled version and links to it.
I have added the library to the bundle and have verified it is in the app using iPhone Explorer
I have verified that the xib file recognized the new view type by removing and selecting the custom view type in the custom class field of the identity inspector.
I have changed all of the #import commands to reflect the <> VS "" change and have gotten the app to compile.
however none of the methods of my custom class can be executed. and an NSLog reports that the class is its base counterpart as opposed to the custom derived class.
I am at a loss and have spend a long time converting all the code I have to work in a library. I am hoping someone can help with this.
On this issue, it turns out that Objective C's compiler does not load the categories and custom classes in the libraries by default. There are 2 ways to overcome this.
And here are your options.
Create an Activation type method on the category that will be called to "Activate" that Class or Category. This will need to be done before the application loads any nib files. And seems like a bit of a pain in the butt. This was however how I originally overcame this issue.
Add linker flags that will tell objective C to load all libraries and attach any and all Categories and Classes within the libraries before executing the application. (this will need to be done, on top of #import(ing) the correct files from their correct locations. I will provide a graphic below. and provide the flags for search purposes
-ObjC is the first one I added, but -all_load really did the trick.
I hope that others can benefit from this experience.

Order of evaluation with relative layouts, best practices and parsing of relative-layout

I read this
"
It used to be that Android would use a single pass to process
RelativeLayout-defined rules. That meant you could not reference a widget
(e.g., via android:layout_above) until it had been declared in the XML. This
made defining some layouts a bit complicated. Starting in Android 1.6,
Android uses two passes to process the rules, so you can now safely have
forward references to as-yet-undefined widgets.
"
I do not know what is the problem maybe is eclipse problem, but even I use 2.3 I still have problems when I reference some view that is not declared jet so for me it seems like android doesn't uses two passes to process the rules for relative layout.
note: I always use #+id/widget_name when I declare the widget and #id/widget_name when I reference that widget from other widget. I have noticed that I can use #+id/widget_name even when I just want to reference that widget. I guess that is wrong but why sometimes is works without any complaints ? In my opinion one widget should be allowed to be declared only ones...
My questions is is really android uses two passes ? and I need some guidelines (best practices) for working with relative layouts
I am little confused about how this relative layout parings are made, so any explanations are welcomed
Thanks
#+id/name creates a new id, if it doesn't already exist. #id/name references an existing id, and will never create one.
I'm not sure if you can use #id/name before #+id/name in the same file. If not, I can think of two workarounds:
Always use #+id/name.
Define all id's in the ids.xml file, and always use #id/name.
This is general information on how Android draw views.
I think that Android passes twice through all the view, but it doesn't pass through each single view once. So if you have a reference from one xml to another it will always work fine, but if you have references inside a single xml you must be carefull to order the elements in the xml correctly. For example, I have view1 and view2 in my RelativeLayout. If I want to refer to view2 from view1 I must declare view2 before view1.