Change view properties after adding it as subview - ios

I'm creating app where i'm using pagedFlowView. I have custom view (mainDetailV) with ImageView as background and label on top. I'm using PagedFlowView delegate method to init all the views in it:
- (UIView *)flowView:(PagedFlowView *)flowView cellForPageAtIndex:(NSInteger)index{
mainDetailV = (MainDetailView *)[flowView dequeueReusableCell];
if (!mainDetailV) {
mainDetailV = [[[NSBundle mainBundle] loadNibNamed:#"MainDetailView" owner:self options:nil] lastObject];
//mainDetailV.layer.cornerRadius = 6;
mainDetailV.layer.masksToBounds = YES;
}
return mainDetailV;
}
It's adding my view 5 times in pageFlowView.
I want to trigger some action, like changing alpha of label, on tapping the imageView, but i don't really know how to do this.
My main question is how can i change properties of this view after it's added to pagedViewController?
Similar question
Access properties of subview

What is the definition of mainDetailV? It seems very strange to have this set as an Ivar
You should create mainDetailV as a local var and store it's contents in a mutable array just before you return it's value. So:
- (UIView *)flowView:(PagedFlowView *)flowView cellForPageAtIndex:(NSInteger)index{
id mainDetailV = [flowView dequeueReusableCell];
if (!mainDetailV) {
mainDetailV = [[[NSBundle mainBundle] loadNibNamed:#"MainDetailView" owner:self options:nil] lastObject];
//mainDetailV.layer.cornerRadius = 6;
mainDetailV.layer.masksToBounds = YES;
}
[usedViewControllers insertObject:mainDetailV atIndex:index];
return mainDetailV;
}
where usedViewControllers is a NSMutableArray instance variable.
Then you can use the delegate method like so:
- (void)flowView:(PagedFlowView *)flowView didTapPageAtIndex:(NSInteger)index;
{
MainDetailView *view = (MainDetailView *)[usedViewControllers objectAtIndex:index];
}

(In addition to my comment)
I have looked into PagedFlowView delegate and there is a method
- (void)flowView:(PagedFlowView *)flowView didTapPageAtIndex:(NSInteger)index;
you can use the integer index to get the cell/page from the flow view that was tapped. If you have this one you can edit its properties.
Hope this helps.

Related

iOS: How to implement MoPub native ad page with AFKPageFlipper every fifth page

I'd like to implement MoPub ads within AFKPageFlipper so that an ad which is a UIView appears every five pages.
The method that returns the view for AFKPAgeFlipper looks like this:
- (UIView *) viewForPage:(NSInteger) pagenr inFlipper:(AFKPageFlipper *) pageFlipper
The code I have that displays my regular view is:
Page* page = self.episode.pages[pagenr - 1];
page.episode = self.episode;
ReaderPageView* view = [[[NSBundle mainBundle] loadNibNamed:#"ReaderPageView"
owner:nil options:nil] firstObject];
view.page = page;
if(pagenr == self.startPage && !self.alreadyStarted) {
self.alreadyStarted = YES;
[view setupFirstPage];
} else {
[self manageCacheHandler:pagenr];
}
The code for displaying an ad is:
NativeFlipperAdPageView* view = [[[NSBundle mainBundle] loadNibNamed:#"NativeFlipperAdPageView"
owner:nil options:nil] firstObject];
if ((self.nativeAd != nil)) {
UIView *view = [self.nativeAd retrieveAdViewWithError:nil];
[self.viewForContent addSubview:view];
NSLog(#"Ad Subview added!");
return view;
}
return view;
However, I don't know how to implement both pieces inside viewForPage method so that an ad is displayed every fifth time and then continue with regular pages. Could anybody help?
Just set a counter variable at global level which gets incremented every time the page is changed. And then check if pageChangeCount % 5 == 0. If true display the ad, else not.

Call DataSource method in awakeFromNib

So the question is like this:
I subclass 2 classes, which is UIView(name: Menu) and UIViewController(name: MainController). In Menu, i used xib file to create it layout. In MainController, i added Menu as subview like this and comform to protocol in Menu.
SliderMenu *sliderMenu = [[[NSBundle mainBundle] loadNibNamed:#"SliderMenu" owner:self options:nil] objectAtIndex:0];
sliderMenu.datasource = self;
sliderMenu.delegate = self;
[self.view addSubview:sliderMenu];
The layout works perfectly, there is no problem with it.
The problem is with DataSource. i call a datasource method in awakeFromNib
- (void)awakeFromNib {
// Alloc data
self.data = [[NSArray alloc] initWithArray:[self.datasource arrayOfData]];
}
and that never even get called. After trying and trying i found out that, sliderMenu.datasource = self;is run after awakeFromNib. Thats is why the datasource method in MainController is never get called.
Question:
How can i solve this problem?
If you put a breakpoint in -awakeFromNib method, you'll see that this method executes as it should.
The thing is, that this method called before datasource assignment, and at this moment your self.datasource is nil.
I suggest you to override the setter of the datasource property and initialize your data there, e.g.
- (void)setDatasource:(id<YourProtocol>)datasource
{
_datasource = datasource;
self.data = [[NSArray alloc] initWithArray:[datasource arrayOfData]];
}
OR
make a public method, say, prepare and do all your initialization there,
- (void)prepare
{
self.data = [[NSArray alloc] initWithArray:[self.datasource arrayOfData]];
}
and call this method after datasource assignment:
SliderMenu *sliderMenu = [[[NSBundle mainBundle] loadNibNamed:#"SliderMenu" owner:self options:nil] objectAtIndex:0];
sliderMenu.datasource = self;
sliderMenu.delegate = self;
[sliderMenu prepare];
[self.view addSubview:sliderMenu];

Best way to access subviews of views instantiated from XIB?

I'm instantiating multiple clone views from a XIB, like this:
UIView *view = [[NSBundle mainBundle] loadNibNamed:#"MyNib" owner:self options:nil][0];
Then I need to access a subview (say, change a label) of every single of those views.
Connecting an element with IBOutlet wont work here (as the reference would be rewrite but the most recent view instantiated).
Here is my best shot at this so far:
for (UIView *subview in myView.subviews) {
if ([subview.restorationIdentifier isEqualToString:#"myTargetElement"]) {
// do something with the view
break;
}
}
So I'm basically iterating though subviews to find my element by restorationIdentifier. I wonder if there is a way to get a direct reference without iteration?
You can use IBOutlets. They need to be made to the custom view subclass though, not to the view controller where you add the view. Something like this works fine,
#import "ViewController.h"
#import "RDView.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
RDView *view = [[NSBundle mainBundle] loadNibNamed:#"RDView" owner:self options:nil][0];
[self.view addSubview:view];
view.topLabel.text = #"Hello";
view.bottomLabel.text = #"Goodbye";
}
What's wrong with reference by outlet? I think it'll work just as fine.
It just matters on how you do the dot referencing.
Example:
UIView *view = [[NSBundle mainBundle] loadNibNamed:#"MyNib" owner:self options:nil][0];
//...
UIView *view_1 = [[NSBundle mainBundle] loadNibNamed:#"MyNib" owner:self options:nil][0];
//...
[view.someLabel setText:#"1"];
[view_1.someLabel setText:#"2"];
Anyways... alternatively, you can give the subviews a specific tag and access them via the -viewWithTag: method.
Example:
Say a UILabel in this 'MyNib' of yours has a tag 100, then you can reference it via:
[view viewWithTag:100];
//like so:
//UILabel *lblTemp = [view viewWithTag:100];
//[lblTemp setText:#"NewText"];

Can't get UITextFieldDelegate to work

I write a custom view CustomViewA : UIView<UITextFieldDelegate>and implements the delegate's methods.
And in the CustomViewA's init I write:
- (id)initWithFrame:(CGRect)frame {
self = [[[NSBundle mainBundle] loadNibNamed:#"CustomViewA" owner:self options:nil] objectAtIndex:0];
if (self) {
//the txtfieldA is a IBOutlet property linked to the nib file.
self.txtfieldA.delegate = self; //not work
}
return self;
}
And in this xib file includes a UITextField control which I set its delegate in the init method.But when I run this and edit the textfield, the delegate's methods are not called.Can anyone tell me why? And how can I fix it??
To load a view which subclass an UIView from a xib file, you can do this way:
// Reusable method to load a class which subclass UIView from a xib.
+ (id)loadNibNamed:(NSString *)nibName ofClass:(Class)objClass andOwner:(id)owner {
if (nibName && objClass) {
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:nibName owner:owner options:nil];
for (id currentObject in objects ){
if ([currentObject isKindOfClass:objClass])
return currentObject;
}
}
return nil;
}
Then add the view in your controller:
myCustomViewA = [self loadNibNamed:#"customviewA" ofClass:[CustomViewA class] andOwner:self];
myCustomViewA.delegate = self; // Or do this in the xib file
[self.view addSubview:myCustomViewA];
Ensure that that the UITextField is correctly wired to the IBOutlet of of CustomViewA.
Otherwise, attempting to set the delegate in init will do nothing,
//if self.myTextField is nil, then this does nothing
self.myTextField.delegate = self;
just simply do not use -(id)init if you init a view from xib files.
and set your UITextField's delegate method in - (void)awakeFromNib..

Delegate reference disappears on modal Popup

This is convoluted, so I will do my best to give as much info as possible. My main UIViewController opens a modal popup in the form of an Info screen.
here is the call from MainViewController
infoPopup = [ModalPopup modalPopupWithDelegate:self];
[infoPopup presentInView:self.view.window];
[self.view addSubview:infoPopup];
and here is the receiving method in ModalPopup
+ (id)modalPopupWithDelegate:(id <ModalPopupDelegate>)dlg {
ModalPopup *info = [[ModalPopup alloc] init];
info.delegate = dlg;
return info;
}
In ModalPopup I create a protocol with an optional method of "modalPopupFinished" and make MainViewController the delegate.
in ModalPopup I've add a UIScrollView and insert 5 UIViews into the scrollview.
I created the views all in the same XIB file
NSString *infoXib;
if (IS_IPAD)
infoXib = #"info_iPad";
else
infoXib = #"info_iPhone";
NSArray *views;
views = [[NSBundle mainBundle] loadNibNamed:infoXib owner:self options:nil];
UIView *v1 = [views objectAtIndex:0];
views = [[NSBundle mainBundle] loadNibNamed:infoXib owner:self options:nil];
UIView *v2 = [views objectAtIndex:1];
views = [[NSBundle mainBundle] loadNibNamed:infoXib owner:self options:nil];
UIView *v3 = [views objectAtIndex:2];
views = [[NSBundle mainBundle] loadNibNamed:infoXib owner:self options:nil];
UIView *v4 = [views objectAtIndex:3];
views = [[NSBundle mainBundle] loadNibNamed:infoXib owner:self options:nil];
UIView *v5 = [views objectAtIndex:4];
NSArray *pages = [NSArray arrayWithObjects:v1, v2, v3, v4, v5, nil];
[self setPagesInArray:pages];
- (void)setPagesInArray:(NSArray *)pages {
if (pages) {
int numberOfPages = pages.count;
[pageScroll setContentSize:CGSizeMake(pageScroll.frame.size.width * numberOfPages, pageHeight)];
pageControl.numberOfPages = numberOfPages;
NSUInteger i = 0;
while (i < numberOfPages) {
UIView *page = [pages objectAtIndex:i];
page.frame = CGRectMake(pageWidth * i, 0, pageWidth, pageHeight);
[pageScroll addSubview:page];
i++;
}
}
}
the Views load fine in the scrollview and I can scroll through them all as expected.
One of the views in the XIB as some buttons and I've made the view a member of the Custom Class ModalPopup. I've wired the buttons to some IBActions in ModalPopup, and they fire as expected.
In ModalPopup I create a close button that fires the delegates "modalPopupFinished" event on MainViewController.
- (void)finishCloseAnimation {
if ([_delegate respondsToSelector:#selector(modalPopupFinished)])
[_delegate modalPopupFinished];
[self removeFromSuperview];
}
No Problems everything works great...except
when I press one of the buttons from the View and goto fire a delegate method, it has lost its brain and can't remember the delegate
- (IBAction)facebook:(id)sender {
if ([_delegate respondsToSelector:#selector(sendLikeFacebook)])
[_delegate sendLikeFacebook];
}
In fact when I get into the Facebook method on ModalPopup everything is nil.
The method that I am trying to fire in MainViewController opens
[self presentViewController:composeController animated:YES completion:nil];
thus I want to open it from the main page.
It sounds to me like you have 2 instances of ModalPopup. Since you say that you wired your buttons to ModalPopup in IB, this leads me to believe you are creating an instance of ModalPopup in the xib which is distinct from the ModalPopup that you have created programmatically. The fact that the ModalPopup that is called when the button is pressed is "completely empty" is further evidence.
If this is the case, instead of programmatically creating the ModalPopup, you should get the instance from the xib, just like you get the views. I would also suspect that you already added the views to the ModalPopup in the xib which means you do not have to manually add them as well.

Resources