Swift: Get All Subviews of a Specific Type and Add to an Array

Swift: Get all subviews of a specific type and add to an array

The filter function using the is operator can filter items of a specific class.

let myViews = view.subviews.filter{$0 is MyButtonClass}

MyButtonClass is the custom class to be filtered for.

To filter and cast the view to the custom type use compactMap

let myViews = view.subviews.compactMap{$0 as? MyButtonClass}

Swift: Recursively cycle through all subviews to find a specific class and append to an array

Your main problem is that when you call getSubviewsOfView(subview as! UIView) (recursively, within the function), you aren't doing anything with the result.

You also can delete the count == 0 check, since in that case the for…in loop will just be skipped. You also have a bunch of unnecessary casts

Assuming your desire is to get a flat array of CheckCircle instances, I think this adaptation of your code should work:

func getSubviewsOfView(v:UIView) -> [CheckCircle] {
var circleArray = [CheckCircle]()

for subview in v.subviews as! [UIView] {
circleArray += getSubviewsOfView(subview)

if subview is CheckCircle {
circleArray.append(subview as! CheckCircle)
}
}

return circleArray
}

How to list out all the subviews in a uiviewcontroller in iOS?

You have to recursively iterate the sub views.

- (void)listSubviewsOfView:(UIView *)view {

// Get the subviews of the view
NSArray *subviews = [view subviews];

for (UIView *subview in subviews) {

// Do what you want to do with the subview
NSLog(@"%@", subview);

// List the subviews of subview
[self listSubviewsOfView:subview];
}
}

Swift - Retrieving subviews

UIViewController doesn't have a subviews property. It has a view property, which has a subviews property:

for subview in self.view.subviews {
// Manipulate the view
}

But typically this is not a good idea. You should instead put the labels you want into an IBOutletCollection and iterate over that. Otherwise you've very tied to the exact set of subviews (which may change).

To create the IBOutletCollection, select all the labels you want in IB, and control-drag them to the source code. It should ask if you want to make a collection array. (Note that there is no promise on the order of this array.)

How to remove all subviews of a view in Swift?

EDIT: (thanks Jeremiah / Rollo)

By far the best way to do this in Swift for iOS is:

view.subviews.forEach({ $0.removeFromSuperview() }) // this gets things done
view.subviews.map({ $0.removeFromSuperview() }) // this returns modified array

^^ These features are fun!

let funTimes = ["Awesome","Crazy","WTF"]
extension String {
func readIt() {
print(self)
}
}

funTimes.forEach({ $0.readIt() })

//// END EDIT

Just do this:

for view in self.view.subviews {
view.removeFromSuperview()
}

Or if you are looking for a specific class

for view:CustomViewClass! in self.view.subviews {
if view.isKindOfClass(CustomViewClass) {
view.doClassThing()
}
}

How to remove all subviews of a certain type

Iterate over your maps subviews and remove all UIImageViews:

func removeDots() {
for case let dot as UIImageView in yourPainMapView.subViews {
dot.removeFromSuperView()
}
}

In case you are using other UIImageView subViews you do not want to remove, subclass UIImageView (class MyDot:UIImage {...}):

for case let dot as MyDot in yourPainMapView.subViews

Get all elements of a particular type of view from superView

You can get all subViews of your TextView, By using following code:

for(UIView * subView in myTextView.subviews ) // here write Name of you TextView 
{
// Here You can Get all subViews of your TextView.
// But For Check subview is UILabel or not ? write following code also.

if([subView isKindOfClass:[UILabel class]]) // Check is SubView Class Is UILabel class
{
// You can write code here for your UILabel;
}
}

How can I loop through all subviews of a UIView, and their subviews and their subviews

Use recursion:

// UIView+HierarchyLogging.h
@interface UIView (ViewHierarchyLogging)
- (void)logViewHierarchy;
@end

// UIView+HierarchyLogging.m
@implementation UIView (ViewHierarchyLogging)
- (void)logViewHierarchy
{
NSLog(@"%@", self);
for (UIView *subview in self.subviews)
{
[subview logViewHierarchy];
}
}
@end

// In your implementation
[myView logViewHierarchy];

SwiftUI watchOS How to display array content as subviews in a single View?

Instead of static QuadActivity.all() you can store your data in the ViewModel:

class QuadViewVM: ObservableObject {
@Published var quadActivities: [QuadActivity] = [
QuadActivity(activityImage: activityImage1, activityTitle: "activity1"),
QuadActivity(activityImage: activityImage2, activityTitle: "activity2"),
QuadActivity(activityImage: activityImage3, activityTitle: "activity3"),
QuadActivity(activityImage: activityImage4, activityTitle: "activity4"),
]
}

In your ContentView you can create a grid by using two ForEach loops (as it's a 2D grid):

struct ContentView: View {
@ObservedObject var quadViewVM = QuadViewVM()
let columnCount = 2
var rowCount: Int {
quadViewVM.quadActivities.count / columnCount
}

var body: some View {
ZStack {
// Horizontal divider
VStack {
Divider()
}
.edgesIgnoringSafeArea(.horizontal)
// Vertical divider
HStack {
Divider()
}
.edgesIgnoringSafeArea(.vertical)

activityGrid
}
}

var activityGrid: some View {
VStack {
ForEach(0 ..< self.rowCount) { row in
HStack {
ForEach(0 ..< self.columnCount) { column in
self.quadView(row: row, column: column)
}
}
}
}
}

func quadView(row: Int, column: Int) -> some View {
let activity = quadViewVM.quadActivities[row * columnCount + column]
return QuadView(activity: activity)
.frame(width: 85.0, height: 100.0)
.buttonStyle(PlainButtonStyle())
}
}

The QuadView is extracted to another function to make it more readable and easier to apply view modifiers.

I'd also recommend passing the whole QuadActivity variable to the QuadView (instead of its single components) - specifically when you need them all:

struct QuadView: View {
let activity: QuadActivity

var body: some View {
...
}
}


Related Topics



Leave a reply



Submit