Swift Find Superview of Given Class with Generics

Search a UIView hierarchy using functional Swift

Like this?

func findTableView(view: UIView) -> UITableView? {
return view as? UITableView ?? view.superview.flatMap(findTableView)
}

This code is just a short-cut of:

func findTableView(view: UIView) -> UITableView? {
if let tableView = view as? UITableView {
return tableView
}
else {
let superview = view.superview
if superview == nil {
return nil
}
else {
return findTableView(superview!)
}
}
}

Using "Nil Coalescing Operator" and flatMap(_:) method on Optional enum.

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
}

Use Generic Protocol to filter array of subviews

Protocols and generics in conjunction with subclassing don't work together very well

Actually you don't need neither the protocol nor the view wrapper class. Subclassing UIView is sufficient.

class CanvasItem : UIView
{
public var scale : CGFloat = 1.0
}

class StickerItem: CanvasItem
{
public var stickerName : String = ""
}

class ShapeItem: CanvasItem
{
public var color: UIColor = .red
}

let shapeItem = ShapeItem()
let stickerItem = StickerItem()
let superview = UIView()
superview.addSubview(shapeItem)
superview.addSubview(stickerItem)

for case let canvasItemView as CanvasItem in superview.subviews {
print(canvasItemView.scale)
}

Create generic function to get indexpath from table and collection view - iOS - Swift

You could do this with two protocols, one that both UITableView and UICollectionView conforms to, and the other that both UITableViewCell and UICollectionViewCell conforms to.

protocol IndexPathQueryable: UIView {
associatedtype CellType
func indexPath(for cell: CellType) -> IndexPath?
}

protocol IndexPathGettable: UIView {
associatedtype ParentViewType: IndexPathQueryable
}

extension UITableView : IndexPathQueryable { }
extension UICollectionView : IndexPathQueryable { }

extension UICollectionViewCell : IndexPathGettable {
typealias ParentViewType = UICollectionView
}
extension UITableViewCell : IndexPathGettable {
typealias ParentViewType = UITableView
}

extension IndexPathGettable where ParentViewType.CellType == Self {
func getIndexPath() -> IndexPath? {
guard let superView = self.superview as? ParentViewType else {
return nil
}
let indexPath = superView.indexPath(for: self)
return indexPath
}
}

Really though, you shouldn't need a getIndexPath method on a table view cell. Cells should not know their index paths. I suggest you reconsider your design.

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];
}
}


Related Topics



Leave a reply



Submit