Comments (5)
Another thing you could do in your non-standard localisation case is to create your own protocol:
protocol LocNibReusable: NibReusable {
static var nibName: String { get }
}
extension LocNibReusable {
/* reasonable default implementations */
static var nibName: String { return String(describing: self) }
static var nib: UINib { return UINib(nibName: nibName, bundle: nil) }
}
extension UITableView {
func register<T: LocNibReusable>(cellClass: T.Type, bundle: Bundle?) {
let nib = UINib(nibNamed: cellClass.nibName, bundle: bundle)
self.register(nib, forCellReuseIdentifier: cellClass.reuseIdentifier)
}
}
from reusable.
What about the suggestion on my second comment? Maybe mixing that with your idea of customBundle
?
protocol LocNibLodable: NibLodable {
static var customBundle: Bundle? { get }
}
extension LocNibLoadable {
static var nib: UINib {
return UINib(named: String(describing: self), bundle: customBundle)
}
// And depending on your needs, you could also provide a default implementation for customBundle
/* static var customBundle: Bundle? { return bundleForCustomLoc() } */
}
And then you'd just have to make your tableViewCells conform to LocNibLoadable
instead of just NibLodable
😉
from reusable.
Your second comment, why didn't I think of that 😆. I should have just done that from the beginning.
Thank you.
from reusable.
Hi,
Thanks for the suggestion, but I fail to see how this would fit efficiently with the Mixin pattern Reusable is providing:
- The core idea of Reusable is to avoid having to call
tableView.register(nib, forCellReuseIdentifier: name)
and to avoid having all those strings prone to typos in your code. - So as you can see in the README, the main benefit of
Reusable
withUITableViewCell
is to be able to calltableView.register(SampleTableViewCell.self)
, with no Strings involved, so no risk of typos (with the compiler telling you at compile time if you did one)
So for your use case and the example you provide, I fail to see how you actually make use of Reusable in the example at the bottom of your post… or how you would use Reusable and pass a bundle
as parameter if you did use Reusable. Because:
- Even if we made the bundle as a parameter for determining the
nib
, like you suggest withstatic func nib(bundle: Bundle?)
, the way Reusable works is you'll not be the one calling thatnib
function. It will be called when you calltableView.dequeueReusableCell(for: indexPath) as SampleTableViewCell
- I don't see how you'd pass the
bundle
you want in that call totableView.dequeueReusableCell(for: indexPath) as SampleTableViewCell
- And if your plan was to pass that bundle at registration time and not dequeue time (which would indeed probably make more sense), this means that you'll not use Reusable anymore when you call
tableView.register(SampleTableViewCell.self)
… - or did you expect to modify that definition of
func register<T>
in Reusable here to take abundle
too? That seems like pulling the strings quite far and changing the API for something only a few people will use (custom localisation being quite unusual and non-standard), "polluting" it for others, right?
I'm not closed to changing the API to allow new usages and concepts, but it should only be for use cases that are common and standard; otherwise if we start that road, people are then gonna ask to be able to pass other parameters (like a value to indicate which nib to use depending on other parameters, if you have one cell class backed by multiple XIBs and want to use one or the other depending on some condition… and we'd go down the rabbit hole)
So overall, I think making nib
take a bundle
as parameter is probably not the best option. What I'd suggest you instead would be to have a global property (or better, a static var
on Bundle
) returning the current bundle for the custom localisation your app is currently using. Then use that to implement var nib: UINib { … }
in your Reusable
cells:
// Extension to access the .lproj bundle corresponding to the current custom localization
extension Bundle {
static var currentLocalization: Bundle {
let currentLocale = UserDefaults.standard.string(for: "CurrentLocale")!
let path = Bundle.main.path(forResource: currentLocale, ofType: "lproj")!
return Bundle(path: path)!
}
}
// Example cell
class SampleTableViewCell: UITableViewCell, NibLoadable {
static var nib: UINib {
return UINib(nibName: String(describing: self), bundle: .currentLocalization)
}
}
// Usage example
tableView.register(SampleTableViewCell.self)
let cell = tableView.dequeueReusableCell(for: indexPath) as SampleTableViewCell
from reusable.
The example you gave is actually how I'm implementing things at the moment.
And if your plan was to pass that bundle at registration time and not dequeue time (which would indeed probably make more sense), this means that you'll not use Reusable anymore when you call
tableView.register(SampleTableViewCell.self)… or did you expect to modify that definition of
func registerin Reusable here to take a
bundle` too? That seems like pulling the strings quite far and changing the API for something only a few people will use (custom localisation being quite unusual and non-standard), polluting it for others, right?
Yes I was expecting that the definition of register
edited or overloaded to take a bundle
. But after thinking about it that wouldn't work well like you said.
Maybe one of these can work
- Create a configuration file for Reusable where if I set a custom bundle the library would use that on
static var nib: UINib
instead of me needing to declare it on everyNibReusable
subclass. Because that would just be - Add a
static var customBundle: Bundle?
on NibLoadable which will be used by thestatic var nib: UINib
variable.
I don't know I'm not sure what the best course of action here.
from reusable.
Related Issues (20)
- getting error on using cellType(for indexPath:)
- Support for new API introduced on iOS 13
- MKMapView support
- Feature request - allow to use UITableViewCell with custom style
- Swift Package Manager: reusable deployment target warning HOT 3
- SPM xibs (Bundle.module) HOT 1
- Xcode 12.5 warnings HOT 2
- Swift tools version update too high, lower version build failed
- UITableViewHeaderFooterView - Warning with NibReusable
- Sure, go ahead!
- ## Summary
- Feature request - access to root xib view
- Support for reusable UITableViewHeaderFooterView subclasses?
- Swift 5 Support? HOT 2
- Undefined symbols when compiling for unit tests HOT 1
- Xcode 11 beta 4 compiler error HOT 1
- loadNibContent always loads nib named after base class HOT 14
- is there a way to override sceneStoryboard for StoryboardSceneBased HOT 2
- Swift Package Manager HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reusable.