Redrawing a view in ios - objective-c

Is it possible to redraw the whole view.
I need it to complete my language settings. The problem is that the language only changes after the views there drawn again. Like you go out of settings and then go in again, then the language is changed. But the moment you save everything, the language stays the same.
So how should i redraw my views, or by best the whole app, after the language change was found?

In ARC:
- (void)setLanguage:(LanguageType)languageType
{
_language = languageType;
//TODO:your settings
[_theWholeView setNeedsDisplay];
}
If that can not work , there is a very troublesome solution , it can reload the whole view.
You can code like this:
In the view.h , you need creat a delegate.
#protocol WholeViewDelegate
- (void)reloadData;
#end
In the view.m
- (void)setLanguage:(LanguageType)languageType
{
_language = languageType;
//TODO:your settings
[_delegate reloadData];
}
In the controller you need to implement the delegate
In the controller.m
- (void)reloadData
{
if(_wholeView)
{
[_wholeView removeFromSuperview];
}
// in the wholeView init method you should refresh your data
_wholeView = [[WholeView alloc] init];
self.view addSubview:_wholeView
}

Yes. Call [UIView setNeedsDisplay] (reference).

Just call setNeedsDisplay.. It will resolve the problem. setNeedsDisplay actually calls the drawRect function in the UIView class by passing the frame of the view as the rectangular parameter. Hope that helps....

Related

Check orientation in AwakeFromNib – Objective-c

I want to check the orientation of the iphone in the AwakeFromNib method. This is my code:
- (void)awakeFromNib
{
orientation = [[UIApplication sharedApplication]statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait)
{
NSLog(#"orientation portrait");
}
else if (orientation == (UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight))
{
NSLog(#"Orientation landscape");
}
}
The logs aren't messaged when I'm turning my iPhone, what's the problem?
Your comments on Michael Dautermann's (now-deleted) answer are contradictory. You said you're creating your view programmatically, but you also talked about “when the view is loaded”.
Either you're creating the view in code, or you're loading it from a nib/storyboard. You can't be doing both with the same view instance.
The fact that your awakeFromNib method isn't being called matches your claim that you are creating the view programmatically. But another possibility is that you are loading the view from a nib but have not correctly set the “Custom Class” of the view in the nib, so it's not actually creating an instance of your view subclass.
If you are truly creating the view programmatically, then somewhere you should have code like this:
view = [[MyView alloc] initWithFrame:someRect];
or maybe this:
view = [[MyView alloc] init];
The second case, under the covers, just calls [self initWithFrame:CGRectZero]. So either way, your view's initWithFrame: method is getting called. So you should override that method and check the interface orientation there.
If you're not creating the view in one of those ways, then edit your question to explain exactly how you are creating it.

Custom UIView Not Showing Accessibility on Voice Over

I'm trying to get voice over working with an openGL view, specifically from the cocos2d framework.
From the Apple Accessibility guide I followed this section: Make the Contents of Custom Container Views Accessible
I've subclassed the view (CCGLView for cocos2d people), which is a UIView, to implement the informal UIAccessibilityContainer protocol.
UIAccessibilityContainer implementation in my subclassed UIView:
-(NSArray *)accessibilityElements{
return [self.delegate accessibleElements];
}
-(BOOL)isAccessibilityElement{
return NO;
}
-(NSInteger)accessibilityElementCount{
return [self accessibilityElements].count;
}
-(NSInteger)indexOfAccessibilityElement:(id)element{
return [[self accessibilityElements] indexOfObject:element];
}
-(id)accessibilityElementAtIndex:(NSInteger)index{
return [[self accessibilityElements] objectAtIndex:index];
}
This code is getting called and -(NSArray *)acessibilityElements is returning an array of UIAccessibilityElements. However the voice over controls are not showing up when I touch the screen. Any ideas on what I'm missing or doing wrong?
Other Information:
I'm using a storyboard and adding the CCGLView to the UIView in the storyboard. The _director.view is the CCGLView that I subclassed.
// Add the director as a child view controller.
[self addChildViewController:_director];
// Add the director's OpenGL view, and send it to the back of the view hierarchy so we can place UIKit elements on top of it.
[self.view addSubview:_director.view];
[self.view sendSubviewToBack:_director.view];
For a while I suspected that because I added the subview that this was causing it not to show up, but I also tried subclassing the UIView in the storyboard the same way but it was also not working.
Also this is how I am creating each UIAccessibilityElement in the array.
UIAccessibilityElement *elm = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:view];
elm.accessibilityFrame = f;
elm.accessibilityLabel = t.letter;
elm.isAccessibilityElement = YES;
elm.accessibilityHint = #"Button";
elm.accessibilityValue = t.letter;
elm.accessibilityTraits = UIAccessibilityTraitButton;
Found a solution that is working now, in case anyone has this problem. -(id)accessibilityElementAtIndex:(NSInteger)index was returning a properUIAccessibilityElement but it looks like it wasn't getting retained by whatever Accessibility API is using it. I made a strong NSArray property to hold the UIAccessibilityElements and now it is working fine.

UIPageViewController Traps All UITapGestureRecognizer Events

It's been a long day at the keyboard so I'm reaching out :-)
I have a UIPageViewController in a typical implementation that basically follows Apple's standard template. I am trying to add an overlay that will allow the user to do things like touch a button to jump to certain pages or dismiss the view controller to go to another part of the app.
My problem is that the UIPageViewController is trapping all events from my overlay subview and I am struggling to find a workable solution.
Here's some code to help the example...
In viewDidLoad
// Page creation, pageViewController creation etc....
self.pageViewController.delegate = self;
[self.pageViewController setViewControllers:pagesArray
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// self.overlay being the overlay view
if (!self.overlay)
{
self.overlay = [[MyOverlayClass alloc] init]; // Gets frame etc from class init
[self.view addSubview:self.overlay];
}
This all works great. The overlay gets created, it gets show over the top of the pages of the UIPageViewController as you would expect. When pages flip, they flip underneath the overlay - again just as you would expect.
However, the UIButtons within the self.overlay view never get the tap events. The UIPageViewController responds to all events.
I have tried overriding -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch per the suggestions here without success.
UIPageViewController Gesture recognizers
I have tried manually trapping all events and handling them myself - doesn't work (and to be honest even if it did it would seem like a bit of a hack).
Does anyone have a suggestion on how to trap the events or maybe a better approach to using an overlay over the top of the UIPageViewController.
Any and all help very much appreciated!!
Try to iterate through UIPageViewController.GestureRecognizers and assign self as a delegate for those gesture and implement
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
Your code may be like this:
In viewDidLoad
for (UIGestureRecognizer * gesRecog in self.pageViewController.gestureRecognizers)
{
gesRecog.delegate = self;
}
And add the following method:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view != self.pageViewController.view]
{
return NO;
}
return YES;
}
The documented way to prevent the UIPageViewController from scrolling is to not assign the dataSource property. If you assign the data source it will move into 'gesture-based' navigation mode which is what you're trying to prevent.
Without a data source you manually provide view controllers when you want to with setViewControllers:direction:animated:completion method and it will move between view controllers on demand.
The above can be deduced from Apple's documentation of UIPageViewController (Overview, second paragraph):
To support gesture-based navigation, you must provide your view controllers using a data source object.

Difference between viewDidLoad and loadView?

Two objective-c methods, -(void) viewDidLoad and -(void)loadView are methods called upon execution of a program but whats the different between them?
Do you mean viewDidLoad and loadView? viewDidLoad is a method called when your view has been fully loaded. That means all your IBOutlets are connected and you can make changes to labels, text fields, etc.
loadView is a method called if you're (typically) not loading from a nib. You can use this method to set up your view controller's view completely in code and avoid interface builder altogether.
You'll typically want to avoid loadView and stick to viewDidLoad.
Use -(void)loadView when you create the view. Typically usage is:
-(void)loadView {
UIView *justCreatedView = <Create view>;
self.view = justCreatedView;
}
Use -(void)viewDidLoad when you customize the appearance of view. Exapmle:
-(void)viewDidLoad {
self.view.backgroundColor = [UIColor blackColor];
...
}
i think you are talking about loadView and viewDidLoad.
loadView is a method that you not using a nib file - you use it to programmatically 'write' your interface
viewDidLoad fires automatically when the view is fully loaded. you can then start interacting with it.
more to read read in the discussion here iPhone SDK: what is the difference between loadView and viewDidLoad?

ipad detect when UIPopoverControllers are dismissed

I have several uiPopoverControllers in my universal iPad app. I now have a requirement to trigger a function once a certain popover has been dismissed. I can do this easily if the user clicks "close" inside the popover, but if they touch the screen to hide the popover, I cannot trigger my function.
I've been googling for some time and cannot seem to find any delegate methods which I might be able to use in my main view controller to capture them. I would love something like didDismissPopoverController - but my guess is it's not available.
IF not, I guess the only thing to do would be to detect the touches and trigger then? Basically I am highlighting a UITableView row and loading the popover. I need to deselect the row - so want to simply call [table reloaddata].
Thanks for any help on this one!
You need to assign a delegate to the UIPopoverController and then implement the - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController method. For example:
#interface FooController : UIViewController <UIPopoverControllerDelegate> {
// ...
}
// ...
#end
When you instantiate the UIPopoverController (say, for this example, in FooController)...
UIPopoverController *popover = // ...
popover.delegate = self;
Then, you would implement the method:
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
// do something now that it's been dismissed
}
Granted, I haven't tested this but it seems like it should work...
Hope this helps!
You can use the popoverControllerDidDismissPopover delegate method after the following assignment:
self.popoverController.delegate = self;
Note that popoverControllerDidDismissPopover delegate method does not get called if you programmatically call [self.popoverController dismissPopoverAnimated:YES].