Trying to get all properties of UIView or UIViewController with the follownig:
func propertysNames()->[String]{
var s = [String]()
for c in Mirror(reflecting: self).children
{
if let name = c.label{
s.append(name)
}
}
return s
}
This works on UIVIewController, but UIView does not seem to return properties, any advice?
Not sure what you are trying to achieve but UIView inherits NSObject. Because of this, you have much of the objc runtime at your disposal. So as an alternative, you could do the following:
import UIKit
extension NSObject {
func propertysNames() -> [String]{
var count : UInt32 = 0
let classToInspect = self.dynamicType
let properties : UnsafeMutablePointer <objc_property_t> = class_copyPropertyList(classToInspect, &count)
var propertyNames : [String] = []
let intCount = Int(count)
for var i = 0; i < intCount; i++ {
let property : objc_property_t = properties[i]
let propertyName = NSString(UTF8String: property_getName(property))!
propertyNames.append(propertyName as String)
}
free(properties)
return propertyNames
}
}
print(UIView().propertysNames())
// prints: "["_mayRemainFocused", "_sensitivitySize", "skipsSubviewEnumeration", "viewTraversalMark", "viewDelegate", "monitorsSubtree", "backgroundColorSystemColorName", "currentScreenScale", "maskView", "_userInterfaceIdiom", "hash", "superclass", "description", "debugDescription", "gesturesEnabled", "deliversTouchesForGesturesToSuperview", "deliversButtonsForGesturesToSuperview", "_shouldReverseLayoutDirection", "leadingAnchor", "trailingAnchor", "leftAnchor", "rightAnchor", "topAnchor", "bottomAnchor", "widthAnchor", "heightAnchor", "centerXAnchor", "centerYAnchor", "firstBaselineAnchor", "lastBaselineAnchor", "_keyboardOrientation", "_touchForceObservable", "_inheritedRenderConfig", "_lightStyleRenderConfig", "_accessoryViewFrame", "unsatisfiableConstraintsLoggingSuspended", "hash", "superclass", "description", "debugDescription", "hash", "superclass", "description", "debugDescription", "userInteractionEnabled", "tag", "layer", "focused", "semanticContentAttribute", "interactionTintColor", "_layoutDebuggingIdentifier", "_countOfMotionEffectsInSubtree", "_maskView", "_ancestorDefinesTintColor", "_ancestorDefinesTintAdjustmentMode", "_presentationControllerToNotifyOnLayoutSubviews", "_rawLayoutMargins", "_inferredLayoutMargins", "_dontUpdateInferredLayoutMargins", "_tracksFocusedAncestors", "_countOfFocusedAncestorTrackingViewsInSubtree", "_mutableLayoutGuides", "_mutableLayoutArrangements", "_hiddenManagedByLayoutArrangementCount", "_pendingHiddenCount", "previewingSegueTemplateStorage", "_continuousCornerRadius", "_canBeParentTraitEnviroment", "_layoutEngine", "_boundsWidthVariable", "_boundsHeightVariable", "_minXVariable", "_minYVariable", "_internalConstraints", "_constraintsExceptingSubviewAutoresizingConstraints", "unsatisfiableConstraintsLoggingSuspended", "_shouldArchiveUIAppearanceTags", "_interactionTintColor", "_backdropMaskViewForGrayscaleTint", "_backdropMaskViewForColorTint", "_backdropMaskViewForFilters", "_backdropMaskViews", "_wantsGeometryChangeNotification", "contentSizeNotificationToken", "layoutMarginsGuide", "readableContentGuide", "hash", "superclass", "description", "debugDescription", "traitCollection", "preferredFocusedView", "center", "bounds", "transform", "collisionBoundsType", "collisionBoundingPath"]\n"
Also, I do see some weirdness applying your code to UIKit objects. Not sure what the variable is that causes it to fail. It seems to work fine on NSObject types written in Swift:
import UIKit
class Fruit {
var type=1
var name="Apple"
var delicious=true
}
var s = [String]()
for c in Mirror(reflecting: Fruit()).children
{
if let name = c.label{
s.append(name)
}
}
print(s)
// works: "["type", "name", "delicious"]\n"
class FruitNSObject: NSObject {
var type:NSNumber=1
var name:NSString="Apple"
var delicious=true
}
s = [String]()
for c in Mirror(reflecting: FruitNSObject()).children
{
if let name = c.label {
s.append(name)
}
}
print(s)
// works: "["type", "name", "delicious"]\n"
s = [String]()
for c in Mirror(reflecting: UIView()).children
{
if let name = c.label {
s.append(name)
}
}
print(s)
// doesn't work: "[]\n"
s = [String]()
for c in Mirror(reflecting: UIViewController()).children
{
if let name = c.label {
s.append(name)
}
}
print(s)
// doesn't work: "[]\n"
So either this is a bug or there is some limitation in the Swift <-> ObjC in the current version of Swift. Perhaps it has to do with what @user3441734 pointed out in his answer.
BTW, all code was run on the most current version of Xcode (that's 7.1.1) in a playground.
import UIKit
let viewController = UIViewController()
let view = UIView()
class MyViewController: UIViewController {
let i = 1
let myView = MyView()
}
class MyView : UIView {
let label = UILabel()
let i = 1
}
Mirror(reflecting: MyViewController()).children.count // 2
Mirror(reflecting: MyView()).children.count // 0
You are right! Just fill the bug report ...
or it is sabotage, because i found this
extension UIView : _Reflectable {
}