Swift Mirror does not return UIVIew property

Trying to get all properties of a UIView or UIViewController using 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 the UIVIewController, but the UIView does not seem to return properties, any tips?

+6
source share
2 answers

Not sure what you are trying to achieve, but UIView inherits NSObject. Because of this, most of the objc runtime is at your disposal. Alternatively, you can 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" 

In addition, I see some oddities when applying your code to UIKit objects. Not sure which variable is causing the error. It seems to work great 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" 

Thus, this is either a mistake or a limitation in Swift ↔ ObjC in the current version of Swift. Perhaps this is due to what @ user3441734 indicated in his answer.

BTW, all the code was launched in the latest version of Xcode (this is 7.1.1) on the playground.

+5
source
 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're right! Just fill out the bug report ...

or is it sabotage because I found it

 extension UIView : _Reflectable { } 
+4
source

All Articles