I momently developing a application with a tab bar and some navigation view controllers in Storyboard using iOS 6 and Xcode 4.5
Usually the app should support all interface orientations but I have two views that only should support portrait mode.
So I added the following code to the view controllers:
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
On a other app I developed without storyboard and navigation view controller on iOS 6 it works but her NOT! :/
I hope someone can help, because I found some other post that where not helpful...
With best regards from Germany
Laurenz
EDIT:
I also tried - Doesn't work! :
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
As far as I can tell, this problem arises because the UITabBarController and UINavigationController are returning their own default values for -(BOOL)shouldAutorotate and -(NSUInteger)supportedInterfaceOrientations.
One solution is to extend both of those classes via categories (or just subclass), in order to return the appropriate values from your own implementations of these methods in your view controller. This is what worked for me (you can just drop this into your App Delegate):
#implementation UITabBarController(AutorotationFromSelectedView)
- (BOOL)shouldAutorotate {
if (self.selectedViewController) {
return [self.selectedViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.selectedViewController) {
return [self.selectedViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
#end
#implementation UINavigationController(AutorotationFromVisibleView)
- (BOOL)shouldAutorotate {
if (self.visibleViewController) {
return [self.visibleViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.visibleViewController) {
return [self.visibleViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
#end
By default, all your view controllers will continue to autorotate. In the two View Controllers that should only support portrait mode, implement the following:
-(BOOL)shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Excellent answer by Jonathan.
I modified his code little bit to handle navigation controller in a single snippet.
- (BOOL)shouldAutorotate {
if (self.selectedViewController) {
if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
return [[[(UINavigationController*)self.selectedViewController viewControllers] lastObject] shouldAutorotate];
}
return [self.selectedViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.selectedViewController) {
if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
return [[[(UINavigationController*)self.selectedViewController viewControllers] lastObject] supportedInterfaceOrientations];
}
return [self.selectedViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
Related
In my React application, I have the following code.
state = {
credentialDeletion: false,
accountDeletion: false
}
static getDerivedStateFromProps(nextProps) {
if (nextProps.accountDeleting) {
return {
accountDeletion: true
}
}
if (nextProps.credentialDeletion) {
return {
credentialDeletion: true
}
}
return null;
}
But this code doesn't work properly. If I remove one condition, then the other works fine. But together, only the first condition works. How should I write this code properly?
You could create an object that you add properties to in each if statement and return that, so that both if statements will be run.
static getDerivedStateFromProps(nextProps) {
const update = {};
if (nextProps.accountDeleting) {
update.accountDeletion = true;
}
if (nextProps.credentialDeletion) {
update.credentialDeletion = true;
}
return update;
}
I'm using ngAudio to control audio tracks (spotify 30 seconds previews) on an ionic app. It all works swell in the browser. However, in both ionic view and the actual demo app, the tracks will only stream when I have the phone vibrate toggle turned to not silent/ring mode. If it's in vibrate mode, the user hears nothing. I've dug all over and can't seem to solve this riddle.
Here's my service:
.factory('PlayerService', function(ngAudio) {
var _play = function(show) {
if (typeof audioObject === "undefined") {
audioObject = ngAudio.load(show.track1_preview);
console.log(audioObject);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
} else if (audioObject.paused) {
audioObject = ngAudio.load(show.track1_preview);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
} else {
audioObject.stop();
audioObject = ngAudio.load(show.track1_preview);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
}
}
var _pause = function(show) {
audioObject.stop();
audioObject.playing = '';
}
return {
play: _play,
pause: _pause
};
Here's the controller:
$scope.playStream = function(show) {
PlayerService.play(show);
$scope.audioObject = audioObject; // this allow for styling the play/pause icons
}
$scope.pauseStream = function(show) {
PlayerService.pause(show);
$scope.audioObject = audioObject; // this allow for styling the play/pause icons
//console.log($scope.audioObject);
}
$scope.togglePlayPause = function(show) {
if (!$scope.audioObject || $scope.audioObject.paused) {
$scope.playStream(show);
} else if (show.track1_preview !== $scope.audioObject.id) {
$scope.playStream(show);
} else {
$scope.pauseStream(show);
}
}
Obviously, it's a bit of a crap user experience if someone has to put the phone off vibrate to hear the tracks.
I'm wondering if this is related to asyncronous stuff and mobile. I just don't know. Giving up after 4 hours of messing with it.
In Protractor, I am trying to write a function to simulate clicking a responsive navigation menu item (i.e. menu is either a bar of dropdowns across the top or a hamburger link if mobile). The structure of the bar is defined by MEANJS with a few id="" attributes mixed in.
It seems to work exactly as I want when I run it one spec at a time, like so:
protractor app/tests/e2e/conf.js --suite mySuite
but when I run with the full test (that only has 4 tests in it), like so:
protractor app/tests/e2e/conf.js
I start to get this error intermittently (source of error is in 2 places below):
Failed: element not visible
Here's my function
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')));
}
});
return deferred.promise;
function clickItNow(mainTab, linkUrl, navBar) {
var link;
if(mainTab) {
// if mainTab was passed, need to
// click the parent first to expose the link
var parentLink;
if (mainTab == 'ACCTADMIN') {
parentLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentLink = navBar.element(by.linkText(mainTab));
}
expect(parentLink.isPresent()).toBeTruthy();
parentLink.click(); // FIRST PLACE ERROR HAPPENS
link = parentLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
link = navBar.element(by.css(linkCssExpression));
}
expect(link.isPresent()).toBeTruthy();
link.click(); // SECOND PLACE ERROR HAPPENS
return deferred.fulfill();
}
};
I have tried to use both of these but neither work:
browser.sleep(500);
browser.driver.wait(protractor.until.elementIsVisible(parentLink));
What NOOB async error am I making?
Self answer... but any better answer will win the green check mark!!!
EDITED - After more problems, found a nice 'waitReady()' contribution from elgalu.
There were a few obvious problems with my original code, but fixing them did not solve the problem. After working through what I could, the solution seemed to be the expect(navBar.waitReady()).toBeTruthy(); lines I added. I also had to split the nested function out. Anyway, here is the new code that seems to be working now. A better (comprehensive) answer will get the green checkmark! I'm pretty sure there's a flaw or 2 here.
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar, deferred);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')), deferred);
}
});
return deferred.promise;
};
function clickItNow(mainTab, linkUrl, navBar, deferred) {
var targetLink;
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
expect(navBar.waitReady()).toBeTruthy();
if(mainTab) {
// if mainTab was passed, neet to
// click the parent first to expose the link
var parentTabLink;
if (mainTab == 'ACCTADMIN') {
parentTabLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentTabLink = navBar.element(by.id('main-menu-' + mainTab));
}
// expect(parentTabLink.isDisplayed()).toBeTruthy();
expect(parentTabLink.waitReady()).toBeTruthy();
parentTabLink.click();
targetLink = parentTabLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
targetLink = navBar.element(by.css(linkCssExpression));
}
expect(targetLink.isDisplayed()).toBeTruthy();
targetLink.click().then(function() {
return deferred.fulfill();
});
}
I want that i can turn the live synchronisation on and off, but it's not getting on again.
function startSync() {
localdbSync = localDB.sync(remoteDB, {live: true});
}
function stopSync() {
localdbSync.cancel();
}
$scope.toggleSync = function () {
if (localDB.sync.canceled == true) {
startSync();
} else {
stopSync();
}
};
Thanks for any hints.
nevermind, same code with using a service now works.
I am creating an application in sencha touch 2.0
i m using navigation view
i m creating an arrangement of numbers in ascending order math quiz
my problem is when i run the application it works fine for first time but when i click on back button and aging enters on the same view its shows me the old number
strenge thing is that on the button text new numbers appears but when i click on the button and get the text it shows me the old number
my code
sequence_user_answer="";
sequence_answer="";
sequence_number1=this.getRandomNumber(99,10);
sequence_number2=this.getRandomNumber(99,10);
sequence_number3=this.getRandomNumber(99,10);
if(sequence_number1==sequence_number2)
{
while(sequence_number1==sequence_number2)
{
sequence_number2=this.getRandomNumber(99,10);
}
}
else if(sequence_number3==sequence_number1 || sequence_number3==sequence_number1)
{
while(sequence_number3==sequence_number2 || sequence_number3==sequence_number1)
{
sequence_number3= this.getRandomNumber(99,10);
}
}
var sequencenumber1=Ext.getCmp('NumberSequence1');
sequencenumber1.setHtml(sequence_number1);
var sequencenumber2=Ext.getCmp('NumberSequence2');
sequencenumber2.setHtml(sequence_number2);
// alert("two");
var sequencenumber3=Ext.getCmp('NumberSequence3');
sequencenumber3.setHtml(sequence_number3);
var label1=Ext.getCmp('lblsequencenumber1');
label1.setHtml("");
var label2=Ext.getCmp('lblsequencenumber2');
label2.setHtml("");
var label3=Ext.getCmp('lblsequencenumber3');
label3.setHtml("");
if(sequence_number1>sequence_number2)
{
if(sequence_number1>sequence_number3)
{
if(sequence_number2>sequence_number3)
{
sequence_answer=sequence_answer+sequence_number3;
sequence_answer=sequence_answer+sequence_number2;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number3;
}
sequence_answer=sequence_answer+sequence_number1;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
}
else
{
if(sequence_number2>sequence_number3)
{
if(sequence_number1>sequence_number3)
{
sequence_answer=sequence_answer+sequence_number3;
sequence_answer=sequence_answer+sequence_number1;
}
else
{
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
sequence_answer=sequence_answer+sequence_number2;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
}
on button tap
getSequenceAnswer:function(selected_button_id)
{
//alert(selected_button_id);
alert(selected_button_id.getHtml()); // here it shows me an old value when i go back and enter again to this view
var ans_audio=Ext.getCmp('answeraudio');
var que_audio=Ext.getCmp('questionaudio');
var result=Ext.getCmp('statuslbl');
if(sequence_count==0)
{
var sequence_label1=Ext.getCmp('lblsequencenumber1');
sequence_label1.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
}
else if(sequence_count==1)
{
var sequence_label2=Ext.getCmp('lblsequencenumber2');
sequence_label2.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
}
else if(sequence_count==2)
{
var sequence_label3=Ext.getCmp('lblsequencenumber3');
sequence_label3.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
if(sequence_answer==sequence_user_answer)
{
que_audio.setUrl("");
ans_audio.setUrl('audio/true.mp3');
ans_audio.play();
this.getTrue(result);
var marks=Ext.getCmp('lblMarks');
sequence_marks = sequence_marks+2;
marks.setHtml(sequence_marks);
var total=Ext.getCmp('lbltotal');
sequence_total_marks= sequence_total_marks+2;
total.setHtml(sequence_total_marks);
}
else
{
que_audio.setUrl("");
ans_audio.setUrl('audio/false.mp3');
ans_audio.play();
this.getFalse(result);
var total=Ext.getCmp('lbltotal');
sequence_total_marks= sequence_total_marks+2;
total.setHtml(sequence_total_marks);
}
}
}
Most likely you can use show listener, which invokes while a container displays. Write your logic to create components dynamically here. Or, as another alternative you can reset your label or other component data inside it.
listeners: {
show: function(list, opts){
// code to reset your comp
}
}