---
title: "Thinking outside of the box"
slug: thinking-outside-of-the-box
section: tech
date: 2016-12-09T13:19:00.000Z
canonical: https://roland.leth.ro/blog/tech/thinking-outside-of-the-box
---

Recently, I stumbled upon a small problem: we have a product details controller which calls a factory method that creates a view with a few `UITextViews` that detect a website, a phone, and an address, respectively, but the latter was not working reliably. Said method only needs the product object to be passed in to properly create the view.

One simple solution would have been to also pass the controller as the target, and a local method as the selector, replace the `UITextView` with a button, set its title to the address and its target & action to the passed in params. Then, inside the product details controller we'd have access to `product.mapUrl`, which points to Google Maps.

But I didn't want to pass those two extra parameters just for this edge case, so after a bit of tinkering around, the solution was to let the `UITextView` display the address, remove its detectors and create a button with the same frame, set its title to `product.mapUrl.absoluteString` and its color to `.clear`, set its target to the factory class, and its action to a new `static` method.

Now, button's action method has a `sender` parameter, which can be used to fetch that `mapUrl`:

```swift
// Has to be class because of the button's action, but we could also create an umbrella class, just for that.
class Factory {

	static func contactInformationView(for product: Product) -> UIView {
		let container = UIView()
		[...]
		addressTextView.dataDetectorTypes = []
		addressTextView.text = product.address
		addressTextView.textColor = .actionColor // Same as other textViews' linkTextAttributes.
		[...]
		let addressButton = UIButton(type: .custom)
		container.addSubview(addressButton)

		addressButton.frame = addressTextView.frame // Or align them with Auto Layout.
		addressButton.addTarget(self, action: #selector(addressTapped(_:)), for: .touchUpInside)
		addressButton.setTitle(product.mapUrl.absoluteString, for: .normal)
		addressButton.setTitleColor(.clear, for: .normal)
		[...]
		return container
	}

	@objc private static func addressTapped(_ sender: UIButton) {
		guard
			let title = sender.title(for: .normal),
			let url = URL(string: title)
			else { return }

		// Do something with url.
	}

}
```

This might look like sacrilege to some, but *"If it's stupid but it works, it's not stupid"* ¯\\\_(ツ)\_/¯. Besides, the point of the post was that sometimes you might find solutions in the most obscure places. Let me know what you think [@roland.leth.ro](https://bsky.app/profile/roland.leth.ro).